栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

CCF CSP 2021-9-2 非零段划分 C语言100分

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

CCF CSP 2021-9-2 非零段划分 C语言100分

CCF CSP 2021-9-2 非零段划分 C语言100分

非零段划分 代码长度595B C语言 正确 100分 耗时46ms 空间使用6.246MB 2021-11-06完成

应该会慢慢更新,0算法基础极限挑战今年12月得CSP。坚持每天一道

题目描述
A1,A2,…,An是一个由 n 个自然数(非负整数)组成的数组。我们称其中 Ai,…,Aj 是一个非零段,当且仅当以下条件同时满足:
·1≤i≤j≤n;
·对于任意的整数 k,若 i≤k≤j,则 Ak>0;
·i=1 或 Ai-1=0;
·j=n 或 Aj+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 个用空格分隔的自然数 A1, A2, … , An。

输出格式
输出到标准输出。

仅输出一个整数,表示对数组 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 个非零段 [1],非零段个数达到最大。

样例4输入
3
0 0 0
样例4输出
0
样例4解释
无论 p 取何值,A 都不含有非零段,故非零段个数至多为 0。

子任务
1、70% 的测试数据满足 n ≤ 1000;
2、全部的测试数据满足 n≤5×10^5,且数组 A 中的每一个数均不超过 10^4
子任务说明什么:满足第一条得70分,满足第二条得100分,一般要注意第二条容易超时,所以要简化算法。

思路:
借用岛屿情况来分析这个题。考虑i足够大的情况,所有的数都被海水淹没了,只有0个岛屿。然后,海平面逐渐下降,岛屿数量出现变化。每当一个凸峰出现,岛屿数就会多一个;每当一个凹谷出现,原本相邻的两个岛屿就被这个凹谷连在一起了,岛屿数减少一个。x[i]为所淹到的高度。
ps:我看其他博主写的是凸峰+1,凹峰-1,if语句中与我相反。

	for(i=1;ix[i+1])
		{
			s[x[i]]--;  //若凸峰被淹没 则岛屿-1 
		}
		if(x[i-1]>x[i]&&x[i] 

若相邻的数相等,则可以看作一个凸峰,所以在上述操作前简化数组,对于相邻相等的数,只保留一个。x[0]和x[j]为0设为边界,则不用考虑首末项的特殊情况,简化代码

	x[0]=0;  //x[0]和x[j]为0设为边界,简化代码 
	x[1]=num[0];
	for(i=1;i 

考虑初始情况:在i=0时,至少有1个凸峰,若所有数全部相等也有1个凸峰。极限情况:所有数全为0则没有凸峰。判断是否为极限情况,初始化凸峰数值。

	for(i=0;i 

最大值则只需要从s[i]得前缀和中找出最大值就是所要的结果。
以下为全部代码:

#include
int main()
{
	int n,i,m=0,j=2,sum=0,fin=0;
	int s[10000]={0};
	scanf("%d", &n);
	int num[n];
	int x[n];
	for(i=0;ix[i+1])
		{
			s[x[i]]--;  //若凸峰被淹没 则岛屿-1 
		}
		if(x[i-1]>x[i]&&x[i]fin?sum:fin;
	}
	printf("%d",fin);
	return 0;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/433383.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号