解题思路:方法:记忆化递归


注意事项:这居然是简单题,我真是无语了,被摁在地上摩擦,刚开始想了半天怎么转尼姆博弈,最后还是放弃了,参考了网上的其它语言代码写了python版和详细注释
参考代码:

def play(cnt, cur, next):#cnt表示剩余球数,cur表示当前取球人拥有的球数是奇数还是偶数,next表示另一个取球人拥有的球数是奇数还是偶数
    if character[cnt][cur][next] is not None:#如果已经计算过的情况直接返回,不再重复判断
        return character[cnt][cur][next]
    if cnt < choice[0]: # 当不能再从cnt中取数时,说明结束了
        if cur & 1 == 1 and next & 1 == 0:#如果当前取球人的球数是奇数并且另一个人是偶数
            return "+" # 胜利
        if cur & 1 == 0 and next & 1 == 1:#如果当前取球人的球数是偶数并且另一个人是奇数
            return "-" # 失败
        return "0" # 否则就是平局
    tie = False # 标记是否出现过平局
    for i in range(3):#遍历取球的取法
        if choice[i] > cnt: # 因为之前对choice进行过排序,所以如果小于,后面也不用取了
            break
        res = play(cnt - choice[i], next, cur + choice[i] & 1)# 剩余球数,取球人进行轮换(一人取一次)
        if res == "-":
            character[cnt][cur][next] = "+"#记录结果
            return "+" # 因为我们对取球人进行了轮换,所以说明原取球人胜利,返回+
        if res == "0":#如果不能胜利,就尽量争取平局
            tie = True
    if tie:#如果出现过平局
        character[cnt][cur][next] = "0"
        return "0"
    character[cnt][cur][next] = "-"#平局也没有的情况才返回-
    return "-"
#注意!以上都是return,即一旦返回接下来的代码都不会再执行了!!!

choice = list(map(int, input().strip().split()))
choice.sort()
begin = list(map(int, input().strip().split()))
character = [[[None, None] for _ in range(2)] for _ in range(1000)] # 存储各种取数情况的结果,因为用的方法是记忆化递归

for x in range(len(begin)):#打印结果
    print(play(begin[x], 0, 0), end = " ")


点赞(0)
 

0.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论