HDU 1016 S-Nim ----SG求值
S-Nim
Time Limit : 5000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 2 Accepted Submission(s) : 1
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
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
WWL
1 /* 2 题意:第二次做题,题意完全忘记。 3 前面都是背景,告诉你Nim是赢和输的规则。 4 后面改成了:选的数字是规定的。 5 6 数字是改变的,用打表划不来! 7 数字大小到10000,所以Hash只要到100就可以了。 8 9 SG的求法有两种, 10 1.是打表的。 11 参考http://www.cnblogs.com/tom987690183/archive/2013/05/30/3108564.html 12 2.是单点求取的。和记忆化搜索很相似。 13 这一题是单点的。 14 */ 15 16 17 #include<iostream> 18 #include<cstdio> 19 #include<cstdlib> 20 #include<cstring> 21 #include<algorithm> 22 using namespace std; 23 24 25 int SG[10003]; 26 int arry[103]; 27 28 29 int make_GetSG(int n)//求单点的。 30 { 31 int i,tmp,Hash[101]={0};//后继的大小开sqrt(N); 32 for(i=1;i<=arry[0];i++) 33 { 34 if(arry[i]>n) 35 break; 36 tmp=n-arry[i]; 37 if(SG[tmp]==-1) 38 SG[tmp]=make_GetSG(tmp); 39 Hash[SG[tmp]]=1; 40 } 41 for(i=0;;i++) 42 if(Hash[i]==0) 43 return i; 44 } 45 46 void make_ini(int m) 47 { 48 int i,j,k,n,x; 49 memset(SG,-1,sizeof(SG)); 50 while(m--) 51 { 52 scanf("%d",&n); 53 k=0; 54 for(i=1;i<=n;i++) 55 { 56 scanf("%d",&x); 57 k=k^make_GetSG(x); 58 } 59 if(k==0)printf("L"); 60 else printf("W"); 61 } 62 printf("\n"); 63 } 64 65 int main() 66 { 67 int k,m,i; 68 while(scanf("%d",&k)>0) 69 { 70 if(k==0)break; 71 for(i=1;i<=k;i++) 72 scanf("%d",&arry[i]); 73 arry[0]=k; 74 sort(arry+1,arry+1+k); 75 scanf("%d",&m); 76 make_ini(m); 77 } 78 return 0; 79 }