【SHTSC 2002】取石子游戏

【题目】

题目描述:
【SHTSC 2002】取石子游戏
样例数据:

【样例 11

输入
6 10

输出
0

【样例 22

输入
2 1
8 4
4 7

输出
0
1
0


【分析】

博弈论好题。

以下内容部分摘自这里

定义 (a,b)(a,b) 为第一堆石子有 aa 个,第二堆石子有 bb 个时的状态。

不妨令 aba\le b,那么显然:

  1. (a,b)(a,b) 是必败态,那么 (k,b),(b,k),(k,a),(a,k)(k,b),(b,k),(k,a),(a,k) 都是必胜态。
  2. 对于每个必败态的 a,ba,b 不会在另一个必败态中出现(由 11 可得出)。
  3. 如果有一个必败态 (a,b)(a,b),那么 (a±k,b±k)(a±k,b±k) 为必胜态。

我们打表,发现:

任意非 00 自然数 aa 一定在一个必败态中出现。且第 ii 个必败态的形式为 (ai,ai+i)(a_i,a_i+i)

aia_i 是满足不在以前必败态中的任何一个数出现的最小非 00 自然数(由 22 可得出)。

证明:

对于 (ai,ai+i)(a_i,a_i+i),假设其为必胜态,那么必然存在一种操作使其转换为必败态。

首先假设我们在 aia_i 中拿出一些石子,使 aia_i 减小到 aia_i',即转换为 (ai,ai+i)(a_i',a_i+i),那么 aia_i' 一定在前面的必败态出现过。由于 ai+ia_i+i 严格单调增,不属于前面任何一项的 bb。此时得到的局面为必胜态(由 11 可得出)。所以不能减小 aia_i

其次若 ai+ia_i+i 减小,得到 (ai,bi)(a_i,b_i'),易得到 biai<ib_i'−a_i<i,显然这是一个必胜态(由 33 可得出)。所以不能减小 ai+ia_i+i

然后也不可能两项同时减小得到必败态,因为前面的必败态的差都小于 ii

所以用反证法,这个结论是对的。

这个时候,我们就需要一个神奇的东西叫贝蒂定理来完成后面的步骤了。

先摘抄一下贝蒂定理的内容。
a,ba,b 是无理数且 1a+1b=1\frac{1}{a}+\frac{1}{b}=1,我们记 A={kakN},B={kbkN}A=\{\lfloor ka\rfloor|k\in N^*\},B=\{\lfloor kb\rfloor|k\in N^*\}
那么 ABA∩B 为空集且 ABA∪B 为正整数集合 NN^*
证明的话就自己去百度看吧。

有了这个定理,我们就可以通过构造合适的 A,BA,B 来求出第 ii 个必败态。

那我们令 b=a+1b=a+1,即 A={kakN},B={ka+kkN}A=\{\lfloor ka\rfloor|k\in N^*\},B=\{\lfloor ka +k\rfloor|k\in N^*\},这样的话,BB 中第 kk 个元素刚好比 AA 中第 kk 个元素大了 kk,就可以满足我们的要求。

这样解出来,发现 a=5+12a=\frac{\sqrt 5+1}{2},刚好也是一个无理数,满足前提。

因此,对于一个状态 (x,y),xy(x,y),x\le y,如果 x=5+12(yx)x=\lfloor\frac{\sqrt 5+1}{2}\cdot(y-x)\rfloor,那就是必败态,否则是必胜态。


【代码】

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	int n,m;
	double temp=(sqrt(5)+1)/2;
	while(~scanf("%d%d",&n,&m))
	{
		if(n>m)  swap(n,m);
		puts(n==(int)(temp*(m-n))?"0":"1");
	}
	return 0;
}