【POJ2311】Cutting Game-SG博弈
测试地址:Cutting Game
题目大意:两个人在玩游戏,游戏规则是这样的:给定一张
做法:这一题是一种SG博弈。
很容易想到用一个数对
再来看怎么求一个状态的SG函数值。我们发现在这个游戏中,一个状态的后继状态可以用两个状态的“组合”来表示,例如
因为共有
以下是本人代码:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int sg[210][210],srt[40010]={0},a,b;
void calc_sg()
{
for(int i=2;i<=200;i++)
for(int j=i;j<=200;j++)
{
if (i<=3&&j<=3) {sg[i][j]=0;continue;}
for(int k=2;2*k<=i;k++)
srt[sg[k][j]^sg[i-k][j]]++;
for(int k=2;2*k<=j;k++)
{
int i1=i,i2=i,j1=k,j2=j-k;
if (i1>j1) swap(i1,j1);
if (i2>j2) swap(i2,j2);
srt[sg[i1][j1]^sg[i2][j2]]++;
}
for(int k=0;;k++)
if (!srt[k]) {sg[i][j]=k;break;}
for(int k=2;2*k<=i;k++)
srt[sg[k][j]^sg[i-k][j]]--;
for(int k=2;2*k<=j;k++)
{
int i1=i,i2=i,j1=k,j2=j-k;
if (i1>j1) swap(i1,j1);
if (i2>j2) swap(i2,j2);
srt[sg[i1][j1]^sg[i2][j2]]--;
}
}
}
int main()
{
calc_sg();
while(scanf("%d%d",&a,&b)!=EOF)
{
if (a>b) swap(a,b);
if (sg[a][b]==0) printf("LOSE\n");
else printf("WIN\n");
}
return 0;
}