hdu 3032 Nim or not Nim? 打sg表

题目链接

给出n堆石子, 每次可以取一堆中的任意x个(x>=1), 或者将一堆石子拆成两堆, 取到最后一堆的胜。

这个题需要打sg表找规律, 打表程序看代码。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define pb(x) push_back(x)
 4 #define ll long long
 5 #define mk(x, y) make_pair(x, y)
 6 #define lson l, m, rt<<1
 7 #define mem(a) memset(a, 0, sizeof(a))
 8 #define rson m+1, r, rt<<1|1
 9 #define mem1(a) memset(a, -1, sizeof(a))
10 #define mem2(a) memset(a, 0x3f, sizeof(a))
11 #define rep(i, a, n) for(int i = a; i<n; i++)
12 #define ull unsigned long long
13 typedef pair<int, int> pll;
14 const double PI = acos(-1.0);
15 const double eps = 1e-8;
16 const int mod = 1e9+7;
17 const int inf = 1061109567;
18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
19 int sg[10000];
20 int mex(int x) {
21     if(~sg[x])
22         return sg[x];
23     int vis[100];
24     mem(vis);
25     for(int i = 0; i<x; i++) {
26         sg[i] = mex(i);
27         vis[sg[i]] = 1;
28     }
29     for(int i = 1; i<=x/2; i++) {
30         int ans = 0;
31         ans ^= sg[i];
32         ans ^= sg[x-i];
33         vis[ans] = 1;
34     }
35     for(int i = 0; ; i++)
36         if(!vis[i])
37             return i;
38 }
39 int main()
40 {
41     int t, n, x;
42     cin>>t;
43     while(t--) {
44         scanf("%d", &n);
45         int ans = 0;
46         while(n--) {
47             scanf("%d", &x);
48             if(x%4==0)
49                 x--;
50             else if(x%4==3)
51                 x++;
52             ans ^= x;
53         }
54         if(ans)
55             cout<<"Alice"<<endl;
56         else
57             cout<<"Bob"<<endl;
58     }
59     return 0;
60 }
原文地址:https://www.cnblogs.com/yohaha/p/5051621.html