首页 > 代码库 > GDUFE-OJ 1361校庆抽奖 翻转

GDUFE-OJ 1361校庆抽奖 翻转

Problem Description:

在舞台中央有一个开奖盒,开奖盒有一个按钮,和一个显示屏,每轮抽奖是过程是这样的。
主持人请K个幸运观众上台,编号为1~K,围着开奖盒。
首先开奖盒上随机显示一个数字S。然后由幸运观众轮流按下按钮。
每次按按钮,数字就会发生变化,直到为0的时候,盒子就会打开,那名观众就会得到里面的奖品。
数字变化的规则如下:
原数字是一个t位二进制数字(不含前导0),按下按钮后原数字的所有位进行翻转,得到变化之后的数字。
比如原数字S = 233,它是二进制是11101001,那么翻转之后是00010110,即10110。
依次按下按钮,11101001 → 10110 → 1001 → 110 → 1 → 0 。
那么第五个按下按钮的幸运观众将会得到奖品。

Input:

输入的第一行包括一个T(T <= 50),代表有T轮抽奖。
每组数组包括两个整数S和K(S < 2^31, K < 10)。

Output:

对于每组数据,输出"Case #x: y"(不包括引号),其中x代表数据的编号,从1开始,y代表该组数据的结果。

Sample Input:

2
233 5
233 4

Sample Output:

Case #1: 5
Case #2: 1

Hints:
两组样例,11101001 → 10110 → 1001 → 110 → 1 → 0 ,其中一个箭头代表按一次按钮  

思路:不找规律,中规中矩翻转,然后去掉前面的0,再翻转……直到剩下全是0.
 1 #include <stdio.h>
 2 int main()
 3 {
 4     int s=0,T,S,K,i,c,a,k,g,h;
 5     while(scanf("%d",&T)!=EOF)
 6         while(T--)
 7     {
 8         int ch[33]={0};
 9         s++;
10         c=1;
11         scanf("%d%d",&S,&K);
12         a=S;
13         for(i=0;a;i++)
14         {
15             ch[i]=a%2;
16             a/=2;//求二进制数,反向存入
17         }
18             for(k=31;k>=0;k--)
19             {
20                 if(ch[k]!=0)break;//去掉后面的0(因为是反向)
21             }
22         for(;;c++)
23         {
24             for(i=0;i<=k;i++)
25             {
26                 if(ch[i]==0)ch[i]=1;//取反啊
27                 else ch[i]=0;
28             }
29             for(;k>=0;k--)
30             {
31                 if(ch[k]!=0)break;//再去掉后面的0
32             }
33             for(i=0,g=0;i<32;i++)
34             {
35                 if(ch[i]!=0)
36                     g=1;
37             }
38             if(g==0)break;//直到全是0
39         }
40         if(c>K)
41             {
42                 c=c%K;
43                 if(c==0)c=K;//此处易漏,such:c=10,K=5   puts(c=5) (not 0)
44             }
45         if(S==0)c=0;
46         printf("Case #%d: %d\n",s,c);
47     }
48     return 0;
49 }

Tips:int是32位二进制数啊-。-

 



GDUFE-OJ 1361校庆抽奖 翻转