HDU 1536 S-Nim
博弈,SG函数
传送门:HDU
题意
取石子游戏。
先给你一个数组长度k,然后是长度为k的数组。表示合法的取石子个数Si。
然后是n,表示n个询问。
每个询问有一个m,m堆石子,每堆mi个。每次操作允许在某一堆石子中取出Si个石子。问你当前状态谁最后赢。
思路
代码
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#define _ ios_base::sync_with_stdio(0);cin.tie(0);
using namespace std;
const int MAXN=10007;
const int oo=0x3f3f3f3f;
typedef long long LL;
const LL loo=4223372036854775807ll;
typedef long double LB;
int sg[MAXN], s[MAXN];
int get_SG(int x,int n)
{
if(sg[x]!=-1) return sg[x];
bool vis[MAXN];
memset(vis, 0, sizeof(vis));
for(int i=0;i<n;i++)
{
if(x>=s[i])
{
get_SG(x-s[i], n);
vis[sg[x-s[i]]]=1;
}
}
for(int i=0;;i++)
{
if(!vis[i]) { sg[x]=i;break; }
}
return sg[x];
}
int main()
{
_
int m;
while(cin>>m)
{
if(m==0) break;
for(int i=0;i<m;i++) cin>>s[i];
memset(sg, -1, sizeof(sg));
int n;cin>>n;
string ss="";
for(int i=0;i<n;i++)
{
int ans=0;
int k=0;cin>>k;
while(k--)
{
int tt;cin>>tt;
int kkk=get_SG(tt, m);
ans=ans^kkk;
cout<<kkk<<endl;
}
if(ans==0) ss+='L';
else ss+='W';
}
cout<<ss<<endl;
}
//system("pause");
return 0;
}