一 题目描述
有三堆石子,分别为7,5,3个每堆,两个人轮流进行如下操作:
选择一堆(石子数不为0);
从这堆石子中取走至少一个,至多全部的石子;
直到有人拿走最后一颗石子,该人算输。
二 思路
当时直觉上这样的题目先手必胜概率很大,但今天才有机会用代码写了一下。
1. 这种棋子数量不多的情况下,完全可以采用暴力求解的手段。
2. 如果基于目前局势,能够导致对手必输的局势,那么目前选手必胜;否则,目前选手必败。这个非黑即白的逻辑解释如下:
我们可以从最终的情况逐步往上添加石子构建到初始情况。比如1-0-0的情况是先手必败情况,那所有一次操作能够形成1-0-0的局势都认为是先手必胜;如果某一个局势不能通过减少石子变为任何一个先手必败的情况,那它只能是通过先手必胜的局势添加石子构建而来,换句话说,无论这个局势下怎么动,都是留给对手一个先手必胜的局势,这种情况下,先手必败。
3. 通过局势生成局势码,避免重复计算,进行剪枝。(实际效果:将递归调用次数从98708次降低到5592次)
三 代码
# -*- coding:UTF-8 -*-
cnt = 0 # 计数器,看调用函数的次数
deadSet = set() # 因为涉及一些重复判断,所以使用一个set记录必输的情况,减少迭代次数
def genDeadNum(curList): # 局势转化为局势码
return "-".join([str(x) for x in sorted(curList, reverse = True)])
def decide(a):
globa

这是一个关于两人轮流从三堆石子中取石子的游戏,目标是避免拿到最后一颗石子。文章介绍了游戏规则,分析了先手必胜的策略,并通过代码展示了如何判断当前局势是否会导致必败状态。最后,讨论了当规则改为谁拿到最后一颗石子谁赢时,游戏策略变为基于异或运算的逻辑。
最低0.47元/天 解锁文章
7852

被折叠的 条评论
为什么被折叠?



