一道比较考思路的题目,这里就不搬题目了既然大家都来看,还是搬题目吧(\(\LaTeX\)好多QwQ)。
题目
题目描述
\(A_1,A_2,...,A_n\) 是一个由 \(n\) 个自然数(非负整数)组成的数组。我们称其中 \(A_i,...,A_j\) 是一个非零段,当且仅当以下条件同时满足:
-
\(1\leq i\leq j\leq n\);
-
对于任意的整数 \(k\),若 \(i\leq k\leq j\),则 \(A_k>0\);
-
\(i=1\) 或 \(A_{i-1}=0\);
-
\(j=n\) 或 \(A_{j+1}=0\)。
下面展示了几个简单的例子: -
\(A=[3,1,2,0,0,2,0,4,5,0,2]\) 中的 \(4\) 个非零段依次为 \([3,1,2]\)、\([2]\)、\([4,5]\) 和 \([2]\);
-
\(A=[2,3,1,4,5]\) 仅有 \(1\) 个非零段;
-
\(A=[0,0,0]\) 则不含非零段(即非零段个数为 \(0\))。
现在我们可以对数组 \(A\) 进行如下操作:任选一个正整数 \(p\),然后将 \(A\) 中所有小于 \(p\) 的数都变为 \(0\)。试选取一个合适的 \(p\),使得数组 \(A\) 中的非零段个数达到最大。若输入的 \(A\) 所含非零段数已达最大值,可取 \(p=1\),即不对 \(A\) 做任何修改。
输入格式
从标准输入读入数据。
输入的第一行包含一个正整数 \(n\)。
输入的第二行包含 \(n\) 个用空格分隔的自然数 \(A_1,A_2,...,A_n\)。
输出格式
输出到标准输出。
仅输出一个整数,表示对数组 \(A\) 进行操作后,其非零段个数能达到的最大值。
样例1输入
11
3 1 2 0 0 2 0 4 5 0 2
样例1输出
5
样例1解释
\(p=2\) 时,\(A=[3,0,2,0,0,2,0,4,5,0,2]\),\(5\) 个非零段依次为 \([3]\)、\([2]\)、\([2]\)、\([4,5]\) 和 \([2]\);此时非零段个数达到最大。
样例2输入
14
5 1 20 10 10 10 10 15 10 20 1 5 10 15
样例2输出
4
样例2解释
\(p=12\) 时,\(A=[0,0,20,0,0,0,0,15,0,20,0,0,0,15]\),\(4\) 个非零段依次为 \([20]\)、\([15]\)、\([20]\) 和 \([15]\);此时非零段个数达到最大。
样例3输入
3
1 0 0
样例3输出
1
样例3解释
\(p=1\) 时,\(A=[1,0,0]\),此时仅有 \(1\) 个非零段 ,非零段个数达到最大。
样例4输入
3
0 0 0
样例4输出
0
样例4解释
无论 \(p\) 取何值,\(A\) 都不含有非零段,故非零段个数至多为 \(0\)。
子任务
\(70\%\) 的测试数据满足 \(n\leq 1000\);
全部的测试数据满足 \(n\leq 5\times 10^5\),且数组 \(A\) 中的每一个数均不超过 \(10^4\)。
思路
其实这是一个结论题。
1.结论
结论就是:
- 如果一个数比旁边两个数都大,那p就+1;
- 如果一个大一个小就不变;
- 如果比两个都小就-1。
整合一下:
2.过程
我们首先把一个数出现的所有位置记录下来,这个我们可以用vector。就像这样:
之后,我们从大到小来看每一个数所在的每一个位置:
这里的auto &t:v[i]
是一个比较新的语法,就是遍历每一个的意思,用于C++14。
其实这里的1-vs[t-1]-vs[t+1]
是一个省略的写法。这里vs是bool数组,表示他有没有访问过。
如果\(t-1\)这个位置访问过,说明\(t-1\)位置数比他大,\(t+1\)也是同理。
如果正好一个比他大,就是\(1-1-0=0\),两个都大就是\(1-1-1=-1\),两个都比他小就是\(1-0-0=1\)。
注意,这里的p指的是非零段个数,也就是说我们不一定求得出真正的题目中的p,不过可以暴力。
最后,就是把这些段数取最大值。
3.整体代码
总结
写得比较短,因为是从一段QQ聊天记录里面粘的,就不补充了。