poj2311(博弈论,sg函数)

对于任何一个人,都不会先剪出1*n或者n*1,应该这样就必败了。

那我们考虑一个状态的后继中,最小的边也是2,这样就可以避免之前的问题,也不需要考虑类似ANTI-SG。

一旦出现2*2,2*3,3*2,这些都成了终止状态,不论怎么剪都会出现1*n,或者n*1

还是考察SG函数

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

int sg[300][300];

int get_sg(int n,int m){
    if(sg[n][m]!=-1) return sg[n][m];
    int vis[1005];
    memset(vis,0,sizeof(vis));
    for (int i=2;i<=n-i;i++)
        vis[get_sg(i,m)^get_sg(n-i,m)]=1;
    for (int i=2;i<=m-i;i++)
        vis[get_sg(n,i)^get_sg(n,m-i)]=1;
    for (int i=0;;i++) if(vis[i]==0) return sg[n][m]=i;
}

int main(){
    int n,m;
    memset(sg,-1,sizeof(sg));
    sg[2][2]=0;
    sg[2][3]=0;
    sg[3][2]=0;
    while(scanf("%d%d",&n,&m)!=EOF){
        if(get_sg(n,m)) printf("WIN
");
        else printf("LOSE
");
    }
return 0;
}
原文地址:https://www.cnblogs.com/lmjer/p/9303803.html