威佐夫博弈
有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。
解:
已知初始情况a,b不同时为0。
定义: 后手有必胜策略的局势,称之为奇异局势。
观察得出第 0 0 0种奇异局势(0,0),当a,b一方为零或者a与b的差值为0时可以一步到达(0,0)。
当选手观察到奇异局势(0,0)时,表示对手已经取完石子,已经胜利。
继续观察,得出第 1 1 1种奇异局势(1,2),当a,b一方为2或者1时;a,b差值为1时,可以一步到达(1,2)。
当玩家观察到奇异局势(1,2)时,有四种行动方案:
- ( 1 , 2 ) → ( 1 , 1 ) (1,2) \rightarrow (1,1) (1,2)→(1,1)
- ( 1 , 2 ) → ( 1 , 0 ) (1,2) \rightarrow (1,0) (1,2)→(1,0)
- ( 1 , 2 ) → ( 0 , 1 ) (1,2) \rightarrow (0,1) (1,2)→(0,1)
- ( 1 , 2 ) → ( 0 , 2 ) (1,2) \rightarrow (0,2) (1,2)→(0,2)
我们发现,不论选择哪种行动,后手玩家都可以一步将其转移到第 0 0 0种奇异局势,导致先手玩家的必败。
不妨继续观察,得到第 2 2 2种奇异局势(3,5),当a,b一方为 3 o r 5 3\space or \space 5 3 or 5时 或者 当a与b差值为2时,可以一步到达(3,5)。
当局势是(3,5)时,可以大致分为 3 3 3 种行动方案:
- 缩小a,b的差值。此时差值为2,缩小差值意味着差值的大小将变为 0 或者 1。如此一来,对方可以一步使局势进入第0, 1种奇异局势。
- 扩大a,b的差值。显然是要取3个石子的那堆,也就是这堆石子将会变为 0 , 1 , 2 {0,1,2} 0,1,2。如此一来,对方可以一步使局势进入第0, 1种奇异局势。
- 维持a,b差值不变。为此需要执行第二种操作,也就是两堆石子一起取相同数字的石子走掉。操作完后,较小的数字将会在 0 , 1 , 2 {0,1,2} 0,1,2中。如此一来,对方可以一步使局势进入第0, 1种奇异局势。
因此局势(3,5)是奇异局势。
到此我们似乎发现了奇异局势的一些规律,比如:
-
奇异局势无法在一次且仅为操作内取完。(0,0)也是,因为无法进行一次操作,此时对方已经获胜。
-
当玩家遇到第 i i i个奇异局势时,无论玩家如何操作,对方可以让该玩家在下一回合遇到第 j ( j < i ) j(j<i) j(j<i)种奇异局势。因此遇到奇异局势可以恒等于失败。
-
观察奇异局势之间的转移似乎基于两种机制。记奇异局势为 ( x , y ) 且 x < y (x,y) \space 且 \space x<y (x,y) 且 x<y
- 缩小差值。如局势(3,5)的第一种行动方案。
- 减小较小值。如局势(3,5)的第2,3种方案。
也就是说我们要保证奇异局势可以向下转移,要保证两种机制的实现。
机制一的保证:较高层的奇异局势 ( x , y ) (x,y) (x,y)的差值 y − x y-x y−x需要比 比其低层的奇异局势的最大差值 多且仅多 1 1 1。因为如果相等就没有意义,如果大于1则不能保证转移。
机制二的保证:较高层的奇异局势 ( x , y ) (x,y) (x,y)的两个值 x , y x,y x,y不能与 较其低层的奇异局势的值 相等。因为如果存在相等,就可以一步转移到另一种奇异局势,导致对方必败,与奇异局势的定义相悖。
搞明白这些规律之后我们就可以来构造更多的奇异局势来找更多的规律了。
对于第 i i i个奇异局势 ( x , y ) (x,y) (x,y)具体的构造方法是:
- 第 0 0 0个奇异局势是 ( 0 , 0 ) (0,0) (0,0)。
- x x x选定为第[0, i)个奇异局势中 未曾出现的最小非负整数。
- y = x + i y = x +i y=x+i
以下是其他的奇异局势:
第3种奇异局势 (4,7)
第4种奇异局势 (6,10)
第5种奇异局势 (8, 13)
第6种奇异局势 (9, 15)
第7种奇异局势 (11, 18)
……
我们通过上面的构造又可以总结出几条结论:
- 任何自然数都包含在且仅包含在一个奇异局势中。
- 任意操作都会使奇异局势转译成非奇异局势
- 通过适当的方法,可以将非奇异局势转换成奇异局势
- 一个局势,要么为非奇异局势,要么为奇异局势
如图:
好了,现在我们离解出这道题很近了,我们只需要判断题目给出的 a , b a,b a,b是否是奇异局势就好了。
但是数据范围很大,递推的方式毫无疑问会超时。
其实我们有一个很好用的公式:
其中a[k]表示第k个奇异局势的a,b[k]表示第k个奇异局势的b,其中k为自然数。
证明如下:
首先我们有Beatty定理:
设a、b是正无理数且 1 a + 1 b = 1 \frac{1}{a} +\frac{1}{b} =1 a1+b1=1。记 P = { ⌊ n a ⌋ ∣ n 为 任 意 的 正 整 数 } , Q = { ⌊ n b ⌋ ∣ n 为 任 意 的 正 整 数 } P=\{ \lfloor na \rfloor | n为任意的正整数\},Q=\{ \lfloor nb \rfloor | n 为任意的正整数\} P={⌊na⌋∣n为任意的正整数},Q={⌊nb⌋∣n为任意的正整数},则P与Q是 N + N^+ N+的一个划分,即 P ∩ Q = ∅ P∩Q=\varnothing P∩Q=∅且 P ∪ Q = N + P∪Q=N^+ P∪Q=N+(正整数集)。
回顾我们之前的这个结论:
*任何自然数都包含在且仅包含在一个奇异局势中。*且a,b不相同的情况下,也就是说全体奇异局势(不包含 ( 0 , 0 ) (0,0) (0,0))的a的集合A和b的集合B也是正整数的一个划分。
我们尝试用一个无理数 ⌊ k u ⌋ \lfloor ku\rfloor ⌊ku⌋来表示a,一个无理数 ⌊ ( u + 1 ) k ⌋ \lfloor(u+1)k\rfloor ⌊(u+1)k⌋来表示b,其中k表示第k个奇异局势,同时 b − a = n b-a=n b−a=n符合定义,其中k为正整数。
也就是说我们有 1 u + 1 u + 1 = 1 \frac{1}{u}+\frac{1}{u+1}=1 u1+u+11=1。解这个方程得出 u = 1 + 5 2 u = \frac{1+\sqrt{5}}{2} u=21+5。
同时将 ( 0 , 0 ) (0,0) (0,0)带入,k=0, 因此k可以等于0。
Q.E.D
代码实现
#include <iostream>
#include <cmath>
using namespace std;
int a, b;
const double lorry = (sqrt(5.0) + 1.0) / 2.0;
int main() {
cin >> a >> b;
if(a < b) swap(a, b);
int k = a - b;
if(b == int(lorry * k))
cout << 0 << endl;
else
cout << 1 << endl;
}