送气球
Time Limit: 2000/1000ms (Java/Others)
Problem Description:
为了奖励近段时间辛苦刷题的ACMer,会长决定给正在机房刷题的他们送气球。N位ACMer的围成了一个圈,会长分别间隔1,2,3,4.......个ACMer送一个气球,请问是不是所有的ACMer都有气球呢?
Output:
如果所有人都有,输出‘YES’,否则输出‘NO’。
Sample Output:
YES
NO
NO
NO
Hint:
N = 5,首先会长给一号和二号ACMer一个糖果,之后给四号一个糖果,按照循环,再给二号一个糖果,再给一号一个糖果,再给一号一个糖果......
解题思路:咋看这道题给的数据n最大是10的9次方,再结合题意,纯找规律题啊。但是菜鸡比赛时测试代码下标写错了,结果半天跑不出结果,比赛完后修改了一下并A了这水题。
给出的提示意思是,先给1号一个糖果,间隔1到2号再给2号糖果,间隔2到4号给其糖果,就这样子循环给。
测试代码找规律:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5 for(int N=3;N<1000;++N){
6 int j=1,t=2;
7 bool a[N],flag=false;
8 memset(a,false,sizeof(a));
9 a[0]=a[1]=true;//下标从0开始
10 while(t<1000000){
11 j=(j+t)%N;//j:0~N-1
12 if(!a[j])a[j]=true;
13 t++;
14 }
15 for(int i=2;i<N;++i){
16 if(!a[i]){flag=true;break;}
17 }
18 if(!flag)cout<<N<<endl;
19 //else cout<<N<<":0"<<endl;
20 }
21 return 0;
22 }
由于间隔t给的是10的6次方,所以找N个ACMer是否都分到糖果只枚举到1000个,这样不用等太久。运行结果是 4 8 16 32 64 。。。熟悉吧!!!这就是规律!!!接下来就好办了,题目给的N最大为10的9次方在int范围内,所以先打表2^i次方,再枚举判断N是否在这里面即可。
AC代码:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5 int a[30]={2},n;
6 bool flag;
7 for(int i=1;i<30;i++)
8 a[i]=2*a[i-1];
9 while(cin>>n){
10 flag=false;
11 for(int i=0;i<30;++i){
12 if(n==a[i]){flag=true;break;}
13 }
14 if(flag)cout<<"YES"<<endl;
15 else cout<<"NO"<<endl;
16 }
17 return 0;
18 }