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("\n");

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("\n");

65     }

66     return 0;

67 }
循环版

 

你可能感兴趣的:(HDU)