HDU 1536 S-Nim(SG博弈)

来源:互联网 发布:阿里云有香港主机 编辑:程序博客网 时间:2024/05/29 14:33

S-Nim

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7117    Accepted Submission(s): 3012


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.
 

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 532 5 123 2 4 74 2 3 7 125 1 2 3 4 532 5 123 2 4 74 2 3 7 120
 

Sample Output
LWWWWL
 

Source
Norgesmesterskapet 2004
 

Recommend
LL   |   We have carefully selected several similar problems for you:  1404 1517 1524 1729 1079


题目大意:

    有M堆石子,堆有hi个石子,有S个操作,每次可以选择拿si个石子,不能拿着失败。


解题思路:

    明显的SG博弈,先打一个SG表,在把各个堆的SG值异或一下就行了。


AC代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;#define mem(a,b) memset((a),(b),sizeof(a))const int maxn=100+3;const int maxi=10000;int op[maxn],S,M,sg[maxi+3];bool used[maxi+3];void make_sg()//打SG表{    sg[0]=0;//0个石子是必负    for(int i=1;i<=maxi;++i)    {        //mem(used,0);        for(int j=0;j<S;++j)//把前面的状态的SG值加入数组            if(i-op[j]>=0)                used[sg[i-op[j]]]=true;        for(int j=0;j<maxi;++j)//找到最小的没出现的SG值            if(!used[j])            {                sg[i]=j;                break;            }        for(int j=0;j<S;++j)//恢复used数组(有时用memset快一些,具体分析决定用哪个)            if(i-op[j]>=0)                used[sg[i-op[j]]]=false;    }}int main(){    while(~scanf("%d",&S)&&S)    {        for(int i=0;i<S;++i)            scanf("%d",&op[i]);        make_sg();        scanf("%d",&M);        while(M--)        {            int num,ans=0,tmp;            scanf("%d",&num);            while(num--)            {                scanf("%d",&tmp);                ans^=sg[tmp];//各个堆异或            }            if(ans)                putchar('W');            else putchar('L');        }        putchar('\n');    }        return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 两个月的小孩不喜欢吃奶粉怎么办 三个多月的宝宝不爱吃奶怎么办 4个月的宝宝不吃奶怎么办 九个月宝宝一直高烧不退怎么办 8个月宝宝不吃辅食怎么办 孩子七个月了母乳不够了怎么办 11个月宝宝吃的太多怎么办 宝宝十一个月了上火眼死太多怎么办 9个月孩子不吃辅食怎么办 y一夜没有睡好现在母乳不够怎么办 喂母乳的婴儿总要吃奶怎么办 宝宝四个月了奶水不够吃怎么办 宝宝出生十天了奶水不够吃怎么办 宝宝晚上不吃奶了奶水多怎么办 我家小孩六个月了奶不够吃怎么办 六个月的宝宝奶不够吃怎么办 宝贝六个月了奶不够吃怎么办 奶不够吃宝宝又不吃奶粉怎么办 婴儿到新环境哭闹不睡觉怎么办 婴儿到陌生地方狂哭不止怎么办 在家里遇到有人有陌生人敲门怎么办 在家里晚上睡觉遇到持刀小偷怎么办 在租房中房东随意调换房间怎么办 梦见熟人当面说我坏话偷东西怎么办 偷了家里的存折拿了钱该怎么办 故意让小偷偷车捉住他怎么办 进屋门正对着厕所门怎么办 楼房对面门上放个镜子我该怎么办 从顺丰发的水果坏了顺丰不管怎么办 汽车塑料件被机头水腐蚀了怎么办 孕期吃了炒菜里面加的香精怎么办 五个月宝宝只长身高不长体重怎么办 孩子6个月奶水越来越少怎么办 孩子快三个月了奶水越来越少怎么办 老婆生完孩子乳房肿胀不下奶怎么办 大人吃了退烧药不出汗怎么办 三岁宝宝抵抗力差总生病怎么办 8个月宝宝发烧39度怎么办 小孩发烧吃了药不退烧怎么办 小孩一直发烧39度左右不退怎么办 九个月宝宝反复发烧39度怎么办