CSP:202109-2 非零段划分
题目描述
是一个由 个自然数(非负整数)组成的数组。我们称其中 是一个非零段,当且仅当以下条件同时满足:
- ;
- 对于任意的整数 ,若 ,则 ;
- 或 ;
- 或 。
下面展示了几个简单的例子:
- 中的 个非零段依次为、、 和 ;
- 仅有 个非零段;
- 则不含非零段(即非零段个数为 )。
现在我们可以对数组 进行如下操作:任选一个正整数 ,然后将 中所有小于 的数都变为 。试选取一个合适的 ,使得数组 中的非零段个数达到最大。若输入的 所含非零段数已达最大值,可取 ,即不对 做任何修改。
输入格式
从标准输入读入数据。
输入的第一行包含一个正整数 。
输入的第二行包含 个用空格分隔的自然数 。
输出格式
输出到标准输出。
仅输出一个整数,表示对数组 进行操作后,其非零段个数能达到的最大值。
样例1输入
11
3 1 2 0 0 2 0 4 5 0 2
样例1输出
5
样例1解释
时,, 个非零段依次为 、、、 和 ;此时非零段个数达到最大。
样例2输入
14
5 1 20 10 10 10 10 15 10 20 1 5 10 15
样例2输出
4
样例2解释
时,, 个非零段依次为 、、 和 ;此时非零段个数达到最大。
样例3输入
3
1 0 0
样例3输出
1
样例3解释
时,,此时仅有 个非零段 ,非零段个数达到最大。
样例4输入
3
0 0 0
样例4输出
0
样例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;
}