EOJ 1068 石子游戏-B

http://acm.cs.ecnu.edu.cn/problem.php?problemid=1068

题意:

  该题比一般的NIMM博弈多了每次取1-m个的限制,容易联想到巴什博奕。

解题思路:

  把每堆数量减少到<=m,使之转化为无限制的NIMM博弈。

  设第 i 堆有ki*(m+1)+si (0 <= si < m+1)个石子,只需判断STATE = (k1*(m+1)+s1, ...ki*(m+1)+si, ...,kn*(m+1)+sn)的状态。

  设对应的state =(s1, ... si, ..., sn),  nim_sum(state) = s1^s2^...^sn;

  1. 若nim_sum(state) = 0, 则state为必败态,由巴什博奕,得 STATE 为必败态。

  //2. 若nim_sum(state) != 0, 则state为必胜态,由巴什博奕,得 STATE 为必胜态。

    2好像写的不对,改一改:

  2.第一步应该使得nim_sum(state)变为零,即把必败态留给对方,具体做法:

  若nim_sum(state) = c != 0,c的最高位为p, 则存在st, 其最高位也为p。令x = c^st, 有 x < st。把 st 变为 x 即可。

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string>
 4 #include <algorithm>
 5 #include <string.h>
 6 #include <stdlib.h>
 7 
 8 using namespace std;
 9 
10 int main()
11 {
12     //freopen("testin.txt", "r", stdin);
13     //freopen("testout.txt", "w", stdout);
14     
15     int t;
16     cin >> t;
17     while(t--)
18     {
19         int a = 0;
20         int n, m;
21         cin >> n >> m;
22         
23         //cout << n << m; 
24         
25         while(n--)
26         {
27             int x;
28             cin >> x;
29             a ^= (x%(m+1)); 
30         }
31         if(a)
32             printf("Win\n");//先手者。 
33         else
34             printf("Lost\n");
35     }
36    
37     return 0;
38 }
View Code

 

  

  

 

posted on 2013-07-07 22:07  KimKyeYu  阅读(300)  评论(0编辑  收藏  举报

导航