(给大家安利一部相关电影《美丽心灵~》)
石子游戏
有若干堆石子,每堆石子的数量有限,合法的移动是选择一堆石子并拿走若干颗(不能不拿),如果轮到某个人时所有的石子都被拿完了,则该人失败。
这是一个先手必胜或者必输的组合博弈游戏,具体必胜或是必输取决于石子个数的值
定义
1.无法进行任何合法移动的局面为P-position(即失败局面)
2.可以通过一次合法移动到达P-positon的点为N-position(一次就够了,想赢的人一定会选这个策略的)
3.所有合法移动都到达N-position的点(即没有任何一次合法移动可以移动到P-positon的点)为P-position
通俗的来说,就是当前选手为N-position,他可以经过合法移动到达P-positon从而使下一个选手必败(第三条定义可能有点难理解,可以理解为你已经输了,不断怎么移动对方都会赢,也就是必胜点 )
怎么表示
有向无环图,每个节点是一个局面状态(只能往前走,不能绕回来,有点像隐马尔可夫??)
每个节点函数g(即局面对应的g函数的值)为:
g
(
x
)
=
m
e
x
{
g
(
y
)
∣
y
是
x
的
后
继
(
即
y
是
x
经
过
有
效
步
骤
可
以
到
达
的
局
面
)
}
g(x)=mex\{g(y)|y是x的后继(即y是x经过有效步骤可以到达的局面)\}
g(x)=mex{g(y)∣y是x的后继(即y是x经过有效步骤可以到达的局面)}(也就是说所有x能到达的局面都放在这个大括号里求一个mex)
对于一个
g
(
x
)
=
0
g(x)=0
g(x)=0的顶点x,它的所有前驱y都满足
g
(
y
)
!
=
0
g(y)!=0
g(y)!=0,对于一个
g
(
x
)
!
=
0
g(x)!=0
g(x)!=0的顶点,必定存在一个后继y满足g(y)=0
g(x)=0就是必败点,!=0代表必胜点
mex函数定义为最小的不属于这个集合的非负整数;
好像有点抽象,还是结合下面的直观理解来看
对于石子游戏,g当且x等于0时才等于0
理解
为了更好的理解上边的定义,举个实例,假如每次必须拿1-3个石子,各个n的g函数的值如下:
当n=0时,也就是当前选手必败点,就是P;
当n=1、2、3时,当前选手对应拿走1、2、3个便可以直接获胜,所以必胜点N;
当n=4时,当前选手不管拿走1、2、3个,下一个选手都可以通过对应拿走3、2、1个从而获胜,所以是当前选手必败点N;
当n=5时,当前选手不管拿走几个,可能会剩下2、3、4个,下个对手就可以对应拿走1、2、3个从而获胜,所以是当前选手必败点N;
以上是靠主观理解来一个一个算的,当n大时这样不可行,所以引入上文提到的g函数(实际是SG函数)来通过递推得到对应值:
首先可知,n=0是必败点为P;n=1、2、3都可以通过一步操作到达0这个p点,所以都是必胜点;n=4,通过合法移动会变成1、2、3,均是已被标记的为N的点,所以是P点(根据定义第三条)这是递推的思路;
可以证明,SG函数(对于一个g(x)=0的顶点x,它的所有前驱y都满足 g(y)!=0。对于一个g(x)!=0的顶点,必定存在一个后继y满足g(y)=0,g(x)=0就是必败点,!=0代表必胜点)刚好符合上边提到的性质。
异或
进一步扩展为:
有n堆,每一堆分别有a1、a2、…、an个小石子,从A开始,A、B两个人轮流抓,每人每次必须从某一堆石子里面抓1-3个,抓走最后一个石子的人获胜。在双方都尽力不犯错的情况下,问A、B谁能赢?
接下来定义有向图游戏的和,设G1、G2、……、Gn是n个有向图游戏,定义游戏G是G1、G2、……、Gn的和(sum),游戏G的移动规则是:任选一个子游戏Gi并移动上面的棋子。SG函数理论为:
g
(
G
)
=
g
(
G
1
)
g
(
G
2
)
…
…
g
(
G
n
)
g(G)=g(G1)^g(G2)^……^g(Gn)
g(G)=g(G1)g(G2)……g(Gn),即游戏的和的SG函数值是它所有子游戏的SG函数值的异或。
参考
题目
Brave Game入门级
代码
我们其实可以直接用上边1-3个石子的结论,由图表可以观察到,当n=0,4,8,12……时,是必败的,也就是(3+1)的倍数;
所以只要先手能够拿完后留下(m+1)的倍数即可,反过来如果先手时,n为(m+1)的倍数,那么先手必输
int main()
{
int c;
scanf("%d",&c);
while(c--)
{
int n,m;
scanf("%d%d",&n,&m);
if(n%(m+1))
printf("first\n");
else
printf("second\n");
}
return 0;