对于一个给定的有向无环图,定义关于图的每个顶点的Sprague-Garundy函数g如下:g(x)=mex{ g(y) | y是x的后继 }。
来看一下SG函数的性质。首先,所有的terminal position所对应的顶点,也就是没有出边的顶点,其SG值为0,因为它的后继集合是空集。然后对于一个g(x)=0的顶点x,它的所有后继y都满足g(y)!=0。对于一个g(x)!=0的顶点,必定存在一个后继y满足g(y)=0。
题意:n*m矩形,轮流切割,矩形面积为1*1时无法切割则输.
每次切割时,都要保证长宽至少为2,若为1*x则下一步对手就能切成1*1,求出SG函数即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
const int N=3e2+20;
int n,m;
int g[N][N];
int grundy(int n,int m)
{
if(g[n][m]!=-1)
return g[n][m];
set<int> s;
//枚举后继状态
for(int i=2;n-i>=2;i++)
s.insert(grundy(i,m)^grundy(n-i,m));
for(int i=2;m-i>=2;i++)
s.insert(grundy(n,i)^grundy(n,m-i));
int res=0;
while(s.count(res))
res++;
return g[n][m]=res;
}
int main()
{
memset(g,-1,sizeof(g));
while(cin>>n>>m)
{
grundy(n,m);
if(g[n][m])
puts("WIN");
else
puts("LOSE");
}
return 0;
}