S-Nim
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7751 Accepted Submission(s): 3266
Problem Description
Arthur and his sister Caroll have been playing a game called Nim for some time now. Nim is played as follows:
The starting position has a number of heaps, all containing some, not necessarily equal, number of beads.
The players take turns chosing a heap and removing a positive number of beads from it.
The first player not able to make a move, loses.
Arthur and Caroll really enjoyed playing this simple game until they recently learned an easy way to always be able to find the best move:
Xor the number of beads in the heaps in the current position (i.e. if we have 2, 4 and 7 the xor-sum will be 1 as 2 xor 4 xor 7 = 1).
If the xor-sum is 0, too bad, you will lose.
Otherwise, move such that the xor-sum becomes 0. This is always possible.
It is quite easy to convince oneself that this works. Consider these facts:
The player that takes the last bead wins.
After the winning player's last move the xor-sum will be 0.
The xor-sum will change after every move.
Which means that if you make sure that the xor-sum always is 0 when you have made your move, your opponent will never be able to win, and, thus, you will win.
Understandibly it is no fun to play a game when both players know how to play perfectly (ignorance is bliss). Fourtunately, Arthur and Caroll soon came up with a similar game, S-Nim, that seemed to solve this problem. Each player is now only allowed to remove a number of beads in some predefined set S, e.g. if we have S =(2, 5) each player is only allowed to remove 2 or 5 beads. Now it is not always possible to make the xor-sum 0 and, thus, the strategy above is useless. Or is it?
your job is to write a program that determines if a position of S-Nim is a losing or a winning position. A position is a winning position if there is at least one move to a losing position. A position is a losing position if there are no moves to a losing position. This means, as expected, that a position with no legal moves is a losing position.
The starting position has a number of heaps, all containing some, not necessarily equal, number of beads.
The players take turns chosing a heap and removing a positive number of beads from it.
The first player not able to make a move, loses.
Arthur and Caroll really enjoyed playing this simple game until they recently learned an easy way to always be able to find the best move:
Xor the number of beads in the heaps in the current position (i.e. if we have 2, 4 and 7 the xor-sum will be 1 as 2 xor 4 xor 7 = 1).
If the xor-sum is 0, too bad, you will lose.
Otherwise, move such that the xor-sum becomes 0. This is always possible.
It is quite easy to convince oneself that this works. Consider these facts:
The player that takes the last bead wins.
After the winning player's last move the xor-sum will be 0.
The xor-sum will change after every move.
Which means that if you make sure that the xor-sum always is 0 when you have made your move, your opponent will never be able to win, and, thus, you will win.
Understandibly it is no fun to play a game when both players know how to play perfectly (ignorance is bliss). Fourtunately, Arthur and Caroll soon came up with a similar game, S-Nim, that seemed to solve this problem. Each player is now only allowed to remove a number of beads in some predefined set S, e.g. if we have S =(2, 5) each player is only allowed to remove 2 or 5 beads. Now it is not always possible to make the xor-sum 0 and, thus, the strategy above is useless. Or is it?
your job is to write a program that determines if a position of S-Nim is a losing or a winning position. A position is a winning position if there is at least one move to a losing position. A position is a losing position if there are no moves to a losing position. This means, as expected, that a position with no legal moves is a losing position.
Input
Input consists of a number of test cases. For each test case: The first line contains a number k (0 < k ≤ 100 describing the size of S, followed by k numbers si (0 < si ≤ 10000) describing S. The second line contains a number m (0 < m ≤ 100) describing the number of positions to evaluate. The next m lines each contain a number l (0 < l ≤ 100) describing the number of heaps and l numbers hi (0 ≤ hi ≤ 10000) describing the number of beads in the heaps. The last test case is followed by a 0 on a line of its own.
Output
For each position: If the described position is a winning position print a 'W'.If the described position is a losing position print an 'L'. Print a newline after each test case.
Sample Input
2 2 5
3
2 5 12
3 2 4 7
4 2 3 7 12
5 1 2 3 4 5
3
2 5 12
3 2 4 7
4 2 3 7 12
0
Sample Output
LWW
WWL
Source
题意:首先输入K 表示一个集合的大小 之后输入集合 表示对于这对石子只能去这个集合中的元素的个数
之后输入 一个m 表示接下来对于这个集合要进行m次询问
之后m行 每行输入一个n 表示有n个堆 每堆有n1个石子 问这一行所表示的状态是赢还是输 如果赢输入W否则L
思路:对于n堆石子 可以分成n个游戏 之后把n个游戏合起来就好了

1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN = 100 + 5; 5 const int MAXM = 10000 + 5; 6 7 int f[MAXN];//f[0]存合法移动个数 8 int sg[MAXM]; 9 bool exist[MAXN];//hash, sg不会超过合法移动个数MAXN 10 11 void getSg(int n) 12 { 13 int i, j; 14 sg[0] = 0; 15 for (i = 1; i <= n; ++i) { 16 memset(exist, false, sizeof(exist)); 17 for (j = 1; j <= f[0] && f[j] <= i; ++j) { 18 exist[sg[i - f[j]]] = true; 19 } 20 for (j = 0; j < MAXN; ++j) { 21 if (!exist[j]) { 22 sg[i] = j; 23 break; 24 } 25 } 26 } 27 } 28 29 30 int main() 31 { 32 int k;//, s; 33 int m; 34 int l, hi; 35 int i, j; 36 int sum; 37 38 while (~scanf("%d", &k)) { 39 if (k == 0) { 40 break; 41 } 42 f[0] = k; 43 for (i = 1; i <= k; ++i) { 44 scanf("%d", &f[i]); 45 } 46 sort(f + 1, f + 1 + k); 47 getSg(10000); 48 49 scanf("%d", &m); 50 for (i = 0; i < m; ++i) { 51 scanf("%d", &l); 52 sum = 0; 53 for (j = 0; j < l; ++j) { 54 scanf("%d", &hi); 55 sum ^= sg[hi]; 56 } 57 if (sum != 0) { 58 printf("W"); 59 } else { 60 printf("L"); 61 } 62 } 63 printf(" "); 64 65 } 66 return 0; 67 }

1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int MAXN = 100 + 5; 5 const int MAXM = 10000 + 5; 6 7 int s[MAXN]; 8 int sg[MAXM]; 9 int n;//s中的个数 10 11 int dfsSg(int x) 12 { 13 if (sg[x] != -1) { 14 return sg[x]; 15 } 16 int i; 17 bool vis[MAXN];//sg范围 18 memset(vis, false, sizeof(vis)); 19 for (i = 0; i < n && s[i] <= x; ++i) { 20 dfsSg(x - s[i]); 21 vis[sg[x - s[i]]] = true; 22 } 23 for (i = 0; i <= x; ++i) { 24 if (!vis[i]) { 25 sg[x] = i; 26 break; 27 } 28 } 29 return sg[x]; 30 } 31 32 33 int main() 34 { 35 int k;//, s; 36 int m; 37 int l, hi; 38 int i, j; 39 int sum; 40 41 while (~scanf("%d", &k)) { 42 if (k == 0) { 43 break; 44 } 45 n = k; 46 for (i = 0; i < k; ++i) { 47 scanf("%d", &s[i]); 48 } 49 sort(s, s + k); 50 memset(sg, -1, sizeof(sg)); 51 scanf("%d", &m); 52 for (i = 0; i < m; ++i) { 53 scanf("%d", &l); 54 sum = 0; 55 for (j = 0; j < l; ++j) { 56 scanf("%d", &hi); 57 sum ^= dfsSg(hi); 58 } 59 if (sum != 0) { 60 printf("W"); 61 } else { 62 printf("L"); 63 } 64 } 65 printf(" "); 66 67 } 68 return 0; 69 }