您的位置:首页 > 其它

HDU 1536 S-Nim

2016-08-09 16:01 309 查看
开始入手的就是博弈了,现在此推荐kuangbin写的这个博弈论总结的知识点了。帮助很大啊!!!好好学习完再做题还是可以学到不少的

这个题就是考虑的SG函数的应用,难点就是每堆看成一个子游戏,SG通过递归可以得到由k个可取集合限制下的各个堆的SG函数值,然后对之进行异或再判断是否为0即可。

这种求SG函数这几天的做题下来发现主要就是按照题目要求模拟推导,利用递归等方法或者如果数字太大了,可以考虑先打表前x个的SG函数值,找规律然后直接得出SG的表达式,这个比较取巧,但有时候也是十分可行的。

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

const int maxn=110;
int k,s[maxn],m,x,h[maxn];
int sg[10010];

int mex(int n)
{
int vis[maxn]={0};

for(int i=1;i<=k;i++)
{
if(n-s[i]<0)
break;
if(sg[n-s[i]]==-1)
{
sg[n-s[i]]=mex(n-s[i]);
}
vis[sg[n-s[i]]]=1;
}
for(int i=0;;i++)
{
if(!vis[i])
{
return i;
}
}

}

int main()
{
while(scanf("%d",&k)!=EOF)
{

if(k==0)
break;
for(int i=1;i<=k;i++)
scanf("%d",&s[i]);
sort(s+1,s+1+k);
memset(sg,-1,sizeof(sg));
sg[0]=0;
scanf("%d",&m);
for(int i=0;i<m;i++)
{
scanf("%d",&x);
int ans=0;
for(int j=1;j<=x;j++)
{
scanf("%d",&h[i]);
if(sg[h[i]]==-1)
sg[h[i]]=mex(h[i]);
ans^=sg[h[i]];
}
if(ans==0)
printf("L");
else
printf("W");

}
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: