[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。

浙公网安备 33010602011771号