威佐夫博弈(Wythoff Game)

威佐夫博弈(Wythoff Game)

一、问题模型

有两堆石子,数量任意,可以不同。两人轮流取石子,每次有两种取法:

  1. 从任意一堆中取走任意多枚石子
  2. 从两堆中同时取走相同数量的石子

取走最后一枚石子的人获胜。问先手是否必胜?

对应题目:洛谷 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,本题保证有确定结果,所以只输出 10

六、总结

威佐夫博弈的核心就是判断当前局面是不是奇异局势

b == floor( (a - b) * (1 + √5) / 2 )

是则先手必败,否则先手必胜。

posted @ 2026-09-22 21:58  leaderling  阅读(2)  评论(0)    收藏  举报