题意:给n堆石头,每堆有hi个,玩家轮流选一堆石头取走x个,x属于集合S;
用sg函数来解,如果对sg函数理解的话,做这题就不会有问题。
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
#include<math.h>
#define inf 0x7fffffff
#define eps 1e-9
#define pi acos(-1.0)
#define P system("pause")
using namespace std;
#define N 10000+5
int s[100+5],sg[N],vis[N];
void get_sg(int n)//求sg数组
{
memset(sg,0,sizeof(sg));
int i, j;
for(i = 0; i < s[0]; i++)
sg[i] = 0;
for(; i <= 10000; i++)//求状态i的sg值
{
memset(vis,0,sizeof(vis));
for(j = 0; j < n; j++)//遍历状态i的后继状态
if(i - s[j] >= 0)
vis[sg[i-s[j]]] = 1;
else break;
for(j = 0; ; j++)//求后继状态的sg中不存在的最小非负整数
if(!vis[j]){
sg[i] = j;
break;
}
}
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int sn;
while(scanf("%d",&sn) && sn)
{
int i;
for(i = 0 ; i < sn; i++)
scanf("%d",&s[i]);
sort(s,s+sn);
get_sg(sn);
int t;
scanf("%d",&t);
while(t--)
{
int n,res = 0;
scanf("%d",&n);
while(n--)
{
int k;
scanf("%d",&k);
res ^= sg[k];//sg定理:游戏的结果是其子游戏结果的异或和
}
if(!res) printf("L");//结果为0,是必败状态
else printf("W");
}
printf("\n");
}
return 0;
}