【CCF-CSP】202109-2非零段划分

在这里插入图片描述
思路:把所有小于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;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值