HDU 1536——S-nim博弈

题目:

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.

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

题意:。。没咋懂

分析: S-nim博弈,主要学习SG打表的方法

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 int s[105],sg[10001];
 6 bool mex[10001];
 7 void get_sg(int t,int n)
 8 {
 9     int i,j;
10     memset(sg,0,sizeof(sg));
11     for(i=1;i<=n;i++)
12     {
13         memset(mex,0,sizeof(mex));
14         for(j=1;j<=t&&s[j]<=i;j++)
15             mex[sg[i-s[j]]]=1;
16         for(j=0;j<=n;j++)
17             if(!mex[j])
18             break;
19         sg[i]=j;
20     }
21 }
22 int main()
23 {
24     int k;
25     while(cin>>k,k)
26     {
27         for(int i=1;i<=k;i++)
28             cin>>s[i];
29         sort(s+1,s+k+1);
30         get_sg(k,10001);
31         int m,n,ans,t;
32         cin>>m;
33         while(m--)
34         {
35             cin>>n;
36             ans=0;
37             for(int i=0;i<n;i++)
38             {
39                 cin>>t;
40                 ans^=sg[t];
41             }
42             if(ans)
43                 cout<<‘W‘;
44             else
45                 cout<<‘L‘;
46         }
47         cout<<endl;
48     }
49     return 0;
50 }

时间: 2024-08-05 11:17:55

HDU 1536——S-nim博弈的相关文章

HDU 5011 Game Nim博弈 (涉及scanf和cin效率比较)

scanf是格式化输入,printf是格式化输出. cin是输入流,cout是输出流.效率稍低,但书写简便. 格式化输出效率比较高,但是写代码麻烦. 流输出操作效率稍低,但书写简便. cout之所以效率低,正如一楼所说,是先把要输出的东西存入缓冲区,再输出,导致效率降低. 缓冲区比较抽象,举个例子吧: 曾经就遇到过这样的情况(类似的), int i; cout<<'a'; cin>>i; cout<<'b'; 运行结果什么都没看到输出,输入一个整型比如3再按回车后ab同

HDU 1536(sg博弈) S-Nim

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 ta

ACM学习历程—HDU 3915 Game(Nim博弈 &amp;&amp; xor高斯消元)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3915 题目大意是给了n个堆,然后去掉一些堆,使得先手变成必败局势. 首先这是个Nim博弈,必败局势是所有xor和为0. 那么自然变成了n个数里面取出一些数,使得xor和为0,求取法数. 首先由xor高斯消元得到一组向量基,但是这些向量基是无法表示0的. 所以要表示0,必须有若干0来表示,所以n-row就是消元结束后0的个数,那么2^(n-row)就是能组成0的种数. 对n==row特判一下. 代码:

HDU 1849 Rabbit and Grass(nim博弈)

题目地址:HDU 1849 初次接触nim博弈,感觉好神奇的说...居然可以跟异或运算扯上关系....给人类的智商跪了...作为地球人我感到很自豪.. 具体证明什么的看这篇博客被.传送门 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #include <math.h> #inclu

HDU 1907 Nim博弈变形

1.HDU 1907 2.题意:n堆糖,两人轮流,每次从任意一堆中至少取一个,最后取光者输. 3.总结:有点变形的Nim,还是不太明白,盗用一下学长的分析吧 传送门 分析:经典的Nim博弈的一点变形.设糖果数为1的叫孤独堆,糖果数大于1的叫充裕堆,设状态S0:a1^a2^..an!=0&&充裕堆=0,则先手必败(奇数个为1的堆,先手必败).S1:充裕堆=1,则先手必胜(若剩下的n-1个孤独堆个数为奇数个,那么将那个充裕堆全部拿掉,否则将那个充裕堆拿得只剩一个,这样的话先手必胜).T0:a1

[Nim博弈]hdu 1850 Being a Good Boy in Spring Festival

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1850 Being a Good Boy in Spring Festival Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4053    Accepted Submission(s): 2394 Problem Description

HDU 1536 sg-NIM博弈类

题意:每次可以选择n种操作,玩m次,问谁必胜.c堆,每堆数量告诉. 题意:sg—NIM系列博弈模板题 把每堆看成一个点,求该点的sg值,异或每堆sg值. 将多维转化成一维,性质与原始NIM博弈一样. 1 // #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #

hdu 5011 (nim博弈模版)

//nim博弈 //有n堆石头,两人轮流每次从一堆中拿至少1,之多全部的石头,没有石头可拿为lose //判断先手是win还是lose # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int main() { int n,i; __int64 a,sum; while(~scanf("%d",&n)) { sum=0; fo

hdu 1907(Nim博弈)

John Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 4407    Accepted Submission(s): 2520 Problem Description Little John is playing very funny game with his younger brother. There is one big bo

HDU Rabbit and Grass 兔子和草 (Nim博弈,水)

思路:简单Nim博弈,只需要将所给的数字全部进行异或,结果为0,则先手必败.否则必胜.知道方法的人1分钟写完代码,不知道的人研究几小时都难写. 1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 //freopen("input.txt", "r", stdin); 6 int t, n, m; 7 while(cin>>t,t) 8 { 9 int ans,tmp;