题解 CF1062A 【A Prank】

这题的难度不高,是一道水模拟。可能大多数人用的是数组,(包括楼上的题解)其实这题可以用两个变量进行迭代就可以了。但是这题坑点不少,我在交的时候 WA 了几遍。

坑点1:

JATC决定通过删除数组中的一些连续元素来恶作剧他的朋友。

注意!是连续的元素。

坑点2(最大的坑点):

那么这题就不是求最长连续上升 (1) 的子序列吗(ldotsldots) 一道大水题,自信的写了一个程序,连样例都没测就交上去:

#include <bits/stdc++.h>
using namespace std;
int n,a,b,ans,len;   //len 用来存目前的子序列长度。 
int main()
{
    cin>>n>>a;
	for(int i=1;i<n;i++)
	{
		cin>>b;
		if(b==a+1)   //序列满足连续上升 1,长度加 1。 
			len++;
		else  
		{
			if(len-1>ans)   //更新答案。注意!!!长度要减去一头一尾。 
				ans=len-1;
			len=0;      //一夜回到解放前。 
		}
		a=b;
	}
	if(len-1>ans)   //最后还要再更新一下,因为有可能满足条件的序列一直到最后。 
		ans=len-1;
	cout<<ans;
    return 0;
}

咦?怎么第二个点就 WA 了。赶紧回去看题。

题目中有一句:并且所有元素都是 ([1,10^3]) 范围内的整数

看似只是数据范围,但也是一个隐藏条件。(从样例 (2) 可以看出)既然上限是 (1000),如果 (999) 之后还有一个数,那么就肯定是 (1000);下限是 (1),那么 (2) 前面就肯定是 (1)

解决方案 & 完整 AC 代码

那么我们就可以把长度为 (n) 的序列看成是长度为 (n+2),前面多出的数是 (0),末尾多出来的一个数就是 (1001)。这样在比较时,就可以解决这个烦人的问题了。

就这样完美的解决了:

#include <bits/stdc++.h>
using namespace std;
int n,a,b,ans,len;
int main()
{
    cin>>n;
    a=0;   //一开始的时候就把 a 设置成 0。 
	for(int i=0;i<=n;i++)   
	{
		if(i==n)   //当此时是第 n+2 个数时。 
			b=1001;    //把 b 赋成 1001。 
		else
			cin>>b;    //否则就正常输出。 
		if(b==a+1)     //接下来都是一样的了。 
			len++;
		else
		{
			if(len-1>ans)
				ans=len-1;
			len=0;
		}
		a=b;
	}
	if(len-1>ans)
		ans=len-1;
	cout<<ans;
    return 0;
}

逃(

原文地址:https://www.cnblogs.com/win10crz/p/12859697.html