【算法】经典博弈论问题——威佐夫博弈 python

目录

  • 威佐夫博弈(Wythoff Game)
  • 【模板】


威佐夫博弈(Wythoff Game)


有两堆石子,数量任意,可以不同,游戏开始由两个人轮流取石子
游戏规定,每次有两种不同的取法
1)在任意的一堆中取走任意多的石子
2)可以在两堆中同时取走相同数量的石子
最后把石子全部取完者为胜者
现在给出初始的两堆石子的数目,返回先手能不能获胜

结论:

小!=(大-小)* 黄金分割比例,先手赢
小=(大-小)* 黄金分割比例,后手赢

证明较复杂,此处略


【模板】


[SHOI2002] 取石子游戏


题目描述

有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法:一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。现在给出初始的两堆石子的数目,你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。

输入格式

输入共一行。

第一行共两个数 a , b a, b a,b,表示石子的初始情况。

输出格式

输出共一行。

第一行为一个数字 1 , 0 1,0 1,0 − 1 -1 1,如果最后你是胜利者则为 1 1 1;若失败则为 0 0 0;若结果无法确定则为 − 1 -1 1

样例输入

8 4

样例输出

1

数据范围

50 % 50\% 50% 的数据满足 a , b ≤ 1000 a, b \le 1000 a,b1000

100 % 100\% 100% 的数据满足 a , b ≤ 1 0 9 a, b \le 10^9 a,b109


code:

import math

# 黄金分割率
phi = (1 + math.sqrt(5)) / 2

a,b=map(int,input().split())
if a > b:
    a, b = b, a  # 确保a <= b
k = (b - a) * phi

# 检查是否为奇异局势
if math.floor(phi * k) == a :
    print(0)
else:
    print(1)

会被卡一个测试点

【算法】经典博弈论问题——威佐夫博弈 python_第1张图片

需要高精度(C++需要long double)

题解:

import math
from decimal import Decimal, getcontext

# 设置高精度
getcontext().prec = 50  # 设置精度为50位小数

# 黄金分割率
phi = (Decimal(1) + Decimal(5).sqrt()) / Decimal(2)

a, b = map(int, input().split())
if a > b:
    a, b = b, a  # 确保a <= b
k = math.floor((b - a) * phi)

# 检查是否为奇异局势
if k == a:
    print(0)
else:
    print(1)

END
如果有更多问题或需要进一步的帮助,可以在评论区留言讨论哦!
如果喜欢的话,请给博主点个关注 谢谢

你可能感兴趣的:(算法,python,开发语言)