思路:把所有小于p的数组元素全部变为0,然后求非零段的最大个数,可以看成,在曲线图上,水平沿y=p
切一刀,然后直线上面的段数就是非零段的个数。要想让直线上面的段数最多,直线就得尽量多的从山腰上面切过去。所以最合适的山腰,就是尽量每条线段都经过的数,就是所有线段范围中出现最多数量的值。
设数组b存每种数字的个数。t为最佳的山腰。遍历之后,将所有小于t的数组元素全部置0,然后再遍历计算非零段的个数。
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
int a[n];
for(int i = 0; i < n; i++) cin >> a[i];
int b[10005] = {0}, t, maxn = 0;
for(int i = 0; i < n-1; i++) {
for(int j = min(a[i], a[i+1])+1; j <= max(a[i], a[i+1]); j++) {
b[j]++;
if(maxn < b[j]) {
maxn = b[j];
t = j;
}
}
}
for(int i = 0; i < n; i++) {
if(a[i] < t) a[i] = 0;
}
int ans = 0;
for(int i = 0; i < n; i++) {
if(!i && a[i] == 0) continue;
else if(!i && a[i]) ans++;
else if(a[i] && a[i-1]==0) ans++;
}
cout << ans;
}