[Luogu && SPOJ] SP7015 题解

SP7015 题解

题意如下

\(n\) 个人,首先有 \(0\) 个朋友的人离开,然后是有 \(1\) 个朋友的人离开,接着是有 \(2\) 个朋友的人离开……直到有 \(n-1\) 个朋友的人离开,求最后剩下几人。

这题就一个个算过去就行了。
\(n=1\),那么这个人肯定没朋友,人就走了,剩下 \(0\) 人。
\(n=2\),无论他们两人是不是朋友,两人都会走,剩下 \(0\) 人。
\(n=3\),(由样例可知,剩下 \(1\) 人)人还没走的时候,无法确定他们是否为朋友,所以此时所有人都有朋友,没人离开。然后是有 \(1\) 个朋友的人离开,此时只能是有两个人互为朋友,所以离开 \(2\) 人,剩下 \(1\) 人,这人实际上没朋友,还要留下来,惨
\(n=4\),和 \(n=3\) 的情况类似,在朋友数为 \(0\)\(1\) 的时候无法确定他们是否为朋友,无人离开。有 \(2\) 个朋友的人离开时,有 \(2\) 个人会离开,剩下 \(2\) 人,这下他们俩要嘛不是朋友,要嘛是朋友,此时只有 \(0\)\(1\) 个朋友的人离开的时候已经过去了,他们也没法离开了。
\(n=5\),依照上面的情况可推出最后剩下了 \(3\) 人。

观察上述例子,可以猜测:\(n\le2\) 时,剩下 \(0\) 人;\(n\ge2\) 时,剩下 \(n-2\) 人。

于是就有了这份代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n[11451419],t;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0); //这两行是给cin和cout加速,可删
	cin>>t;
	for(ll i=0;i<t;++i){
		cin>>n[i];
		if(n[i]>=2){
			n[i]=n[i]-2;
		}
		else 
		if(n[i]<2){
			n[i]=0;
		}
	}
	for(ll i=0;i<t;++i){
		cout<<n[i]<<endl;
	}
	return 0;
}

过了,这就证明猜测是对的。

去 SPOJ 上一看,这题 \(n\)\(t\) 的范围都是 \([1,10^{5}]\),所以不用开 long long,开 int 就能过。

优化:

#include<bits/stdc++.h>
using namespace std;
int n[11451419],t;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0), cout.tie(0); 
	cin>>t;
	for(int i=0;i<t;++i){
		cin>>n[i];
		cout<<max(n[i]-2,0)<<endl;
        //若 n[i]<=2,则 n[i]-2 的值为负数,会输出 0,n[i]>=2 时则会输出n[i]-2
	}
	return 0;
}

同样也过了。
另外附上双倍经验 CF23B,用这题代码就可以AC。

posted @ 2023-11-17 20:34  FurippuWRY  阅读(24)  评论(0)    收藏  举报