CSP202109-2 非零段划分(c++)

104 阅读2分钟

CSP:202109-2 非零段划分

题目描述

A1,A2,,AnA_1, A_2, \cdots, A_n 是一个由 nn 个自然数(非负整数)组成的数组。我们称其中 Ai,,AjA_i, \cdots, A_j 是一个非零段,当且仅当以下条件同时满足:

  • 1ijn1 \le i \le j \le n
  • 对于任意的整数 kk,若 ikji \le k \le j,则 Ak>0A_k > 0
  • i=1i= 1Ai1=0A_{i-1} = 0
  • j=nj = nAj+1=0A_{j+1} = 0

下面展示了几个简单的例子:

  • A=[3,1,2,0,0,2,0,4,5,0,2]A = [3, 1, 2, 0, 0, 2, 0, 4, 5, 0, 2] 中的 44 个非零段依次为[3,1,2][3, 1,2][2][2][4,5][4, 5][2][2]
  • A=[2,3,1,4,5]A = [2, 3, 1, 4, 5] 仅有 11 个非零段;
  • A=[0,0,0]A = [0, 0, 0] 则不含非零段(即非零段个数为 00)。

现在我们可以对数组 AA 进行如下操作:任选一个正整数 pp,然后将 AA 中所有小于 pp 的数都变为 00。试选取一个合适的 pp,使得数组 AA 中的非零段个数达到最大。若输入的 AA 所含非零段数已达最大值,可取 p=1p=1,即不对 AA 做任何修改。

输入格式

从标准输入读入数据。

输入的第一行包含一个正整数 nn

输入的第二行包含 nn 个用空格分隔的自然数 A1,A2,,AnA_1, A_2, \cdots, A_n

输出格式

输出到标准输出。

仅输出一个整数,表示对数组 AA 进行操作后,其非零段个数能达到的最大值。

样例1输入

11
3 1 2 0 0 2 0 4 5 0 2

样例1输出

5

样例1解释

p=2p = 2 时,A=[3,0,2,0,0,2,0,4,5,0,2]A = [3, 0, 2, 0, 0, 2, 0, 4, 5, 0, 2]55 个非零段依次为 [3][3][2][2][2][2][4,5][4, 5][2][2];此时非零段个数达到最大。

样例2输入

14
5 1 20 10 10 10 10 15 10 20 1 5 10 15

样例2输出

4

样例2解释

p=12p = 12 时,A=[0,0,20,0,0,0,0,15,0,20,0,0,0,15]A = [0, 0, 20, 0, 0, 0, 0, 15, 0, 20, 0, 0, 0, 15]44 个非零段依次为 [20][20][15][15][20][20][15][15];此时非零段个数达到最大。

样例3输入

3
1 0 0

样例3输出

1

样例3解释

p=1p = 1 时,A=[1,0,0]A = [1, 0, 0],此时仅有 11 个非零段 [1][1],非零段个数达到最大。

样例4输入

3
0 0 0

样例4输出

0

样例4解释

无论 pp 取何值,AA 都不含有非零段,故非零段个数至多为 00

子任务

70%70\% 的测试数据满足 n1000n \le 1000

全部的测试数据满足 n5×105n \le 5 \times 10^{5},且数组 AA 中的每一个数均不超过 10410^{4}

code

#include<iostream>
#include<set>
using namespace std;

int number[500000]={0};
int number1[500000]={0};
int main(){
	int n,max=0,qwe=0;
	set<int>st;
	cin>>n;
	int mn;
	for(int b=0;b<n;b++){
		cin>>mn;
		if(number[qwe]!=mn){
			qwe++;
			number[qwe]=mn;
			st.insert(number[qwe]);
		}
	}
	n=qwe+1;
	int asd=0;
	for(int a=0,key=0,zero=1;a<n;a++){
		if(number[a]==0)
			asd=1;
		if(number[a])
			zero=1;
		else zero=0;
		if(key==0&&zero==1){
			max++;
			key=1;
		}
		if(key==1&&zero==0){
			key=0;
		}
	}
	if(asd==0)
		max--;
	for(int a=0,key=0,zero=1,qwe=0,rty;a<n;a++){
		if(number[a]){
			if(a==0){
				if(number[1]<number[0])
					number1[number[0]]--;
				}
			else if(a==n-1){
				if(number[n-2]<number[n-1])
					number1[number[a]]--;
			}
			else if(number[a]>number[a-1]&&number[a]>number[a+1])
				number1[number[a]]--;
			else if(number[a]<number[a-1]&&number[a]<number[a+1])
				number1[number[a]]++;
		}
	}
	int mmm=0,mmn=0;
	for(set<int>::iterator it=st.begin();it!=st.end();it++){
		mmn+=number1[*it];
		if(mmn>mmm)
			mmm=mmn;
	}
	if(mmm>0)
		max+=mmm;
	cout<<max;
	return 0;
}