目录
- 威佐夫博弈(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,b≤1000;
100 % 100\% 100% 的数据满足 a , b ≤ 1 0 9 a, b \le 10^9 a,b≤109。
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)
会被卡一个测试点
需要高精度(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
如果有更多问题或需要进一步的帮助,可以在评论区留言讨论哦!
如果喜欢的话,请给博主点个关注 谢谢