[POJ2311]Cutting Game(博弈Multi-SG函数)

题目描述

传送门
大意:给出n×m的方格纸片,一次只能剪一刀,最先得到1×1纸片的人获胜。

题解

首先剪一个纸片的时候会把它剪成两个,那么这个纸片的后继的SG取值应该是这两个纸片的SG值取异或。这个很好理解,就相当于是把它分成了两个游戏。
还有就是不能从1开始枚举(题目给的范围是2),否则会出错。究竟是为什么我也不大清楚,调的时候发现如果从1枚举的话到2*2就会出错。

代码

#include
#include
#include
using namespace std;

const int N=200;
const int max_n=1005;

int n,m;
int sg[max_n][max_n];
bool ext[max_n];

inline void get_sg(){
    memset(sg,0,sizeof(sg));

    for (int i=2;i<=N;++i)
      for (int j=2;j<=N;++j){
        memset(ext,0,sizeof(ext));
        for (int k=2;k1;++k)
          ext[sg[k][j]^sg[i-k][j]]=true;
        for (int k=2;k1;++k)
          ext[sg[i][k]^sg[i][j-k]]=true;
        for (int k=0;;k++)
          if (!ext[k]){
            sg[i][j]=k;
            break;
          }
      }
}

int main(){
    get_sg();
    while (~scanf("%d%d",&n,&m)){
        if (!sg[n][m]) printf("LOSE\n");
        else printf("WIN\n");
    }
}

总结

范围什么的不要搞错了,尤其是ext的范围。

你可能感兴趣的:(题解,博弈)