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 即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }