威佐夫博弈(Wythoff Game)
威佐夫博弈(Wythoff Game)
一、问题模型
有两堆石子,数量任意,可以不同。两人轮流取石子,每次有两种取法:
- 从任意一堆中取走任意多枚石子
- 从两堆中同时取走相同数量的石子
取走最后一枚石子的人获胜。问先手是否必胜?
对应题目:洛谷 P2252 取石子游戏
二、结论
设两堆石子数量为 a, b,且 a >= b,令 d = a - b。
记黄金分割比 φ = (1 + √5) / 2 ≈ 1.618。
- 如果
b == floor(φ * d),先手必败(输出0) - 否则先手必胜(输出
1)
三、为什么是这个结论
威佐夫博弈的必败态(奇异局势)有一个规律:
第 k 个必败态为:
( floor(k * φ), floor(k * φ) + k )
也就是说,必败态的两堆差值 d = k,较小的一堆恰好等于 floor(k * φ)。
反过来,给定任意局面 (a, b)(a >= b),只要判断:
b == floor( (a - b) * φ )
成立就是必败态,否则是必胜态。
四、AC 代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll a, b;
cin >> a >> b;
if (a < b) swap(a, b);
long double t = (1 + sqrt(5.0L)) / 2; //题目对精度有要求,double精度不够
ll tt = t * (a - b);
if (b != tt) cout << 1 << '\n';
else cout << 0 << '\n';
return 0;
}
五、易错点
- 必须先保证
a >= b,否则差值d会是负数,判断出错 - 黄金分割比要用浮点精度较高的类型(如
long double),否则a, b接近 10^9 时会因为精度问题判断错误 - 题目输出要求是
1 / 0 / -1,本题保证有确定结果,所以只输出1或0
六、总结
威佐夫博弈的核心就是判断当前局面是不是奇异局势:
b == floor( (a - b) * (1 + √5) / 2 )
是则先手必败,否则先手必胜。

浙公网安备 33010602011771号