UVA12293 Box Game —— SG博弈

题目链接:https://vjudge.net/problem/UVA-12293

 

 

 

题意:

两人玩游戏,有两个盒子,开始时第一个盒子装了n个球, 第二个盒子装了一个球。每次操作都将刷量少的盒子的球倒掉,然后再从数量多的盒子中拿出若干个球放到空盒子里,最终状态为(1,1),达到这个状态的玩家获胜。

 

题解:

1.由于每次都是倒掉数量少的那个盒子,再对数量多的盒子进行分割,所以可以把规则简化为:初始时有n个球,每次只能拿走不多于n/2的球,最终状态为1个球,达到这个状态的玩家获胜。

2.简化游戏规则之后,可知这是一个典型的SG博弈,但是由于n的范围很大,不能直接求SG值,那就打表找规律,如下:

可知,当n为 2^i - 1时,先手输;否则先手赢。

 

 

代码一:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const int INF = 2e9;
15 const LL LNF = 9e18;
16 const int MOD = 1e9+7;
17 const int MAXN = 100+10;
18 
19 int SG[MAXN], vis[MAXN];
20 void table()
21 {
22     SG[1] = 0;
23     for(int i = 2; i<=35; i++)
24     {
25         memset(vis, 0, sizeof(vis));
26         for(int j = (i+1)/2; j<i; j++) vis[SG[j]] = 1;
27         for(int j = 0;;j++) if(!vis[j]) {
28             SG[i] = j;
29             break;
30         }
31     }
32     for(int i = 1; i<=32; i++) printf("%-2d ",i); putchar('\n');
33     for(int i = 1; i<=32; i++) printf("%-2d ",SG[i]); putchar('\n');
34 /*
35     1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
36     0  1  0  2  1  3  0  4  2  5  1  6  3  7  0  8  4  9  2  10 5  11 1  12 6  13 3  14 7  15 0  16
37 */
38 }
39 
40 bool judge(int x)
41 {
42     x++;
43     int bit = 0;
44     while(x)
45     {
46         bit += x&1;
47         x >>= 1;
48     }
49     return bit==1;
50 }
51 
52 
53 int main()
54 {
55 //    table();
56     int n;
57     while(scanf("%d", &n) &&n)
58     {
59         if(judge(n)) printf("Bob\n");
60         else printf("Alice\n");
61     }
62 }
View Code

 

代码二:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const int INF = 2e9;
15 const LL LNF = 9e18;
16 const int MOD = 1e9+7;
17 const int MAXN = 100+10;
18 
19 int SG[MAXN], vis[MAXN];
20 void table()
21 {
22     SG[1] = 0;
23     for(int i = 2; i<=32; i++)
24     {
25         memset(vis, 0, sizeof(vis));
26         for(int j = (i+1)/2; j<i; j++) vis[SG[j]] = 1;
27         for(int j = 0;;j++) if(!vis[j]) {
28             SG[i] = j;
29             break;
30         }
31     }
32     for(int i = 1; i<=32; i++) printf("%-2d ",i); putchar('\n');
33     for(int i = 1; i<=32; i++) printf("%-2d ",SG[i]); putchar('\n');
34 /*
35     1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
36     0  1  0  2  1  3  0  4  2  5  1  6  3  7  0  8  4  9  2  10 5  11 1  12 6  13 3  14 7  15 0  16
37 */
38 }
39 
40 int main()
41 {
42 //    table();
43     int n;
44     while(scanf("%d", &n) &&n)
45     {
46         if(n&(n+1)) printf("Alice\n");
47         else printf("Bob\n");
48     }
49 }
View Code

 

posted on 2018-01-24 15:54  h_z_cong  阅读(185)  评论(0编辑  收藏  举报

导航