题意:给出若干堆石头和若干种取法。两个人轮流从这些石子堆中取石子,规则:(1)每次只能从一堆里取 (2)取出石子的数量值是S中的一个元素(3) 不能按规则取石子者负
求先手必胜还是必败
第一次做博弈题,只会套SG函数,权当练习,避免比赛真出了,一点都不会。
#include<iostream>
#include<stdio.h>
#include<map>
#include<vector>
#include<cmath>
#include<string>
#include<cstring>
#include<set>
using namespace std;
#define L(x) x<<1
#define R(x) x<<1|1
#define M(x,y) (x + y)>>1
#define LL long long
#define N 105
int s[N],h[N];
int mark[N*N];
int flag[N];
int n,m;
void sg(int x)
{
int i,j,k;
mark[0] = 0;
for(i = 1;i <= x;i++)
{
memset(flag,0,sizeof(flag));
for(j = 1;j <= n;j++)
{
if(i - s[j] >= 0)
flag[mark[i - s[j]]] = 1;
}
for(j = 0;j <= 101;j++)
{
if(!flag[j])
{
mark[i] = j;
break;
}
}
}
}
int main()
{
int i,j,k,l;
int ans;
while(scanf("%d",&n) && n)
{
for(i = 1;i <= n;i++)
{
scanf("%d",&s[i]);
}
sg(10000);
scanf("%d",&m);
for(i = 1;i <= m;i++)
{
scanf("%d",&k);
for(j = 1;j <= k;j++)
{
scanf("%d",&h[j]);
}
for(j = 2,ans = mark[h[1]];j <= k;j++)
{
ans = ans^mark[h[j]];
}
if(ans)
printf("W");
else
printf("L");
}
printf("\n");
}
return 0;
}