http://acm.hdu.edu.cn/showproblem.php?pid=1536
S-Nim 博弈 需要用SG 处理
最简单的S-Nim博弈是 每一堆可以任取正整数个 比如说 k 可以变成 k-1,k-2,k-3,······0
本题所可以取的数量有了限制 所以要SG处理 把原始数量可以对应到 S-Nim 里面的数量 是多对一的关系
如果原始数量n取过之后可以变成 S-Nim 里面的0,1,2,3,4,····· k-1 而没有 k 的话 那么n就对应到 S-Nim里面的 k
然后就变成最初的S-Nim了
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<stack>
#include<algorithm>
using namespace std;
//#pragma comment(linker,"/STACK:1000000000,1000000000")
#define LL long long
const int INF=0x3f3f3f3f;
const int N=105;
const int M=10005;
int choose[N];
int k[M];
int n;
int dp(int x)
{
if(k[x]!=-1)
return k[x];
int visited[N];
memset(visited,false,sizeof(visited));
for(int i=0;i<n;++i)
{
if(x-choose[i]<0)
break;
visited[dp(x-choose[i])]=true;
}
for(int i=0;i<=n;++i)
if(visited[i]==false)
{k[x]=i;break;}
return k[x];
}
int main()
{
//freopen("data.txt","r",stdin);
while(scanf("%d",&n)!=EOF,n)
{
for(int i=0;i<n;++i)
scanf("%d",&choose[i]);
sort(choose,choose+n);
memset(k,-1,sizeof(k));
int m;
scanf("%d",&m);
while(m--)
{
int l;
scanf("%d",&l);
int w=0;
while(l--)
{
int tmp;
scanf("%d",&tmp);
w=(w^dp(tmp));
}
if(w)
printf("W");
else
printf("L");
}
printf("\n");
}
return 0;
}
浙公网安备 33010602011771号