Mutli-SG游戏 ——学习笔记

来源:互联网 发布:sketchup2016软件下载 编辑:程序博客网 时间:2024/06/15 05:10

还是先给出Mutli-SG的定义:

Multi-SG 游戏规定,在符合拓扑原则的前提下,一个单一游戏的后继可以为多个单一游戏。
Multi-SG 其他规则与 SG 游戏相同。

关于这种游戏,Jia Zhihao神犇也没过多的解释,但他有说依然能用SG函数表示,那么SG函数不是需要配合SG定理,SG定理是什么?一个游戏的和的SG值等于下面多个单一游戏的SG值之和,那么拆成的多个单一游戏,其实也可以同之前的SG函数一样定义,一针见血,无论怎么拆,SG定理依旧成立。不过建议这时候重新推导一下SG函数的变化,可能会与不拆的情况有冲突。

例题 POJ 3537 Crosses and Crosses

题目大意:
已知有一行N个格子,初始全为空白,每次可以在某个空白的格子上打X,如果在某一个人操作之后出现连续三个X,那么判定这个操作的人胜利,给出N,判断先手是否有必胜策略。
首先,如果一个格子已经打上X,那么他周围的四个格子都无法摆放了,这里写图片描述
如图,如果你在这四个红格子上放X,那么接下来对手一定有策略使得三X连线,你就输了,而对手也深知这一点,于是乎,每个X周围的四个格子就成了禁区,而再往两边就可以再放了(周围还有别的X除外),而每放一个X,就有周围格子成为禁区,那么为了不输我们只能放在不是禁区的格子,所以到此这道题就变成了谁无法在非禁区的格子放X(所有格子都成为禁区),那么他就输了。

如果一开始放一个X,原来一整条格子就分成两个小的片段(也有情况只有一个),此时小的片段依然满足这个定理,所以现在有没有发现,我们已经将一个未知的游戏转换成已知的游戏——Mutli-SG游戏!用f[i]表示连续的i个格子组成的棋盘对应的SG值,那么有

f[0]=0
f[1]=f[2]=f[3]=1
f[i]=mex(f[i-3],f[i-4],f[i-5],f[1]^f[i-6],f[2]-f[i-7]……)
(前提保证这些下标是有意义的)

但本菜鸡并不知道必输时的规律,由于n<=2000,所以可以直接写一个求SG函数的代码,然后O(1)判断。

代码如下:

#include<cstdio>#include<cstring>using namespace std;int n,f[2005];bool vs[2005];int main(){    f[0]=0; f[1]=f[2]=f[3]=1;    for (int i=4;i<=2000;i++)    {        memset(vs,0,sizeof(vs));        if (i>2) vs[f[i-3]]=1;        if (i>3) vs[f[i-4]]=1;        if (i>4) vs[f[i-5]]=1;        for (int j=1;j<=(i-5)/2;j++)          vs[f[j]^f[i-j-5]]=1;        for (int j=0;;j++)          if (!vs[j]) {f[i]=j; break;}    }    scanf("%d",&n);    if (f[n]) printf("1"); else printf("2");    return 0;}
原创粉丝点击