hdu 1536 NIM博弈 (模板)

推荐文章

博弈论初步:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561002.html

博弈解决思想:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561005.html

NIM游戏:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561008.html

关于SG函数:http://www.cnblogs.com/Knuth/archive/2009/09/05/1561007.html

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<string>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<map>
 9 #include<iomanip>
10 #include<climits>
11 #include<string.h>
12 #include<stdlib.h>
13 #define INF 1e11
14 #define MAXN 60
15 using namespace std;
16 
17 int k, a[100], f[10001];
18 int mex(int p)
19 {
20     int i, t;
21     bool g[101] = { 0 };
22     for (i = 0; i<k; i++)
23     {
24         t = p - a[i];
25         if (t<0)    break;
26         if (f[t] == -1)
27             f[t] = mex(t);
28         g[f[t]] = 1;
29     }
30     for (i = 0;; i++)
31     {
32         if (!g[i])
33             return i;
34     }
35 }
36 
37 int main()
38 { 
39     int n, i, m, t, s;
40     while (scanf("%d", &k), k) {
41         for (i = 0; i<k; i++)
42             scanf("%d", &a[i]);
43         sort(a, a + k);
44         memset(f, -1, sizeof(f));
45         f[0] = 0;
46         scanf("%d", &n);
47         while (n--){
48             scanf("%d", &m);
49             s = 0;
50             while (m--) {
51                 scanf("%d", &t);
52                 if (f[t] == -1)  f[t] = mex(t);
53                 s = s^f[t]; 
54             }
55             if (s == 0)
56                 printf("L");
57             else
58                 printf("W"); 
59         }
60         printf("
");
61     }
62     return 0;
63 }
递归版
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstdlib>
 4 #include<cstring>
 5 #include<string>
 6 #include<queue>
 7 #include<algorithm>
 8 #include<map>
 9 #include<iomanip>
10 #include<climits>
11 #include<string.h>
12 #include<stdlib.h>
13 #define INF 1e11
14 #define MAXN 60
15 using namespace std;
16 
17 
18 
19 int sg[10010];
20 int k, knum[110];
21 int flag[110];
22 
23 
24 int met(int n)
25 {
26     int i, ans = 0;
27     memset(flag, 0, sizeof(flag));
28     for (i = 0; i < k; i++)
29         if (n - knum[i] >= 0)
30             flag[sg[n - knum[i]]] = 1;
31     for (i = 0; i <= 101; i++)
32         if (flag[i] == 0) return i;
33 }
34 
35 
36 void Sprague_Grundy()
37 {
38     int i;
39     for (i = 1; i <= 10000; i++)
40         sg[i] = met(i);
41 }
42 
43 
44 int main()
45 {
46     int i, n, l, num, ans;
47     while (~scanf("%d", &k) && k)
48     {
49         for (i = 0; i < k; i++)
50             scanf("%d", &knum[i]);
51         Sprague_Grundy();
52         scanf("%d", &n);
53         while (n--)
54         {
55             ans = 0;
56             scanf("%d", &l);
57             while (l--)
58             {
59                 scanf("%d", &num);
60                 ans ^= sg[num];
61             }
62             printf(ans == 0 ? "L" : "W");
63         }
64         printf("
");
65     }
66     return 0;
67 }
循环版
原文地址:https://www.cnblogs.com/usedrosee/p/4254595.html