Python每日一练-----除数博弈

本文介绍了一个关于爱丽丝和鲍勃玩除数游戏的问题,分析了博弈过程并利用数学归纳法证明了先手优势。当n为偶数时,先手玩家(爱丽丝)必胜;当n为奇数时,先手玩家必败。解题代码展示了两种简洁高效的实现方式,通过判断n是否为偶数来确定胜负。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

☀(day47:P44)

目录

📝题目:

🚩题目分析:

💡解题思路:

🌟解法一:

🌈代码实现

🌟解法二:

 🌈代码实现

✏代码注释 


📝题目:

爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。

最初,黑板上有一个数字 n 。在每个玩家的回合,玩家需要执行以下操作:

  • 选出任一 x,满足 0 < x < n 且 n % x == 0 。
  • 用 n - x 替换黑板上的数字 n 。

如果玩家无法执行这些操作,就会输掉游戏。(1 <= n <= 1000)

只有在爱丽丝在游戏中取得胜利时才返回 true 。假设两个玩家都以最佳状态参与游戏。

⭐示例 1:

输入:n = 2

输出:true

解释说明:爱丽丝选择 1,鲍勃无法进行操作。

⭐示例 2:

输入:n = 3

输出:false

解释说明:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。

🚩题目分析:

分析博弈过程根据规律解题。

💡解题思路:

🌟解法一:

  1. n=1 的时候,区间 (0, 1) 中没有整数是 n的因数,所以此时 Alice 败。
  2. n = 2 的时候,Alice 只能拿 1,n 变成 1,(因为 0 < x < n,所以Bob不能拿1)Bob 无法继续操作,故Alice 胜。
  3. n = 3的时候,Alice 只能拿 1,n 变成 2,根据 n = 2的结论,我们知道此时 Bob 会获胜,Alice 败。
  4. n=4 的时候,Alice 能拿 1 或 2,如果Alice 拿 1,根据 n = 3 的结论,\text{Bob}Bob 会失败,Alice 会获胜。
  5. n = 5 的时候,Alice 只能拿 1,根据n=4 的结论,Alice 会失败。
  6. ......

我们猜想:n 为奇数的时候Alice(先手)必败,n 为偶数的时候 Alice (先手)必胜。

我们使用数学归纳法证明。

n = 1 和 n = 2时结论成立。

n > 2 时,假设n ≤ k 时该猜想成立,则 n=k+1 时:

如果 k为偶数,则 k + 1 为奇数,x 是k+1 的因数,只可能是奇数,而奇数减去奇数等于偶数,且 k+1−x ≤ k,故轮到 Bob 的时候都是偶数。而根据我们的猜想假设 n ≤ k 的时候偶数的时候先手必胜,故此时无论Alice 拿走什么,Bob 都会处于必胜态,所以Alice 处于必败态。
如果 k为奇数,k+1 为偶数,x 可以是奇数也可以是偶数,若Alice 减去一个奇数,那么 - k+1−x 是一个小于等于 k 的奇数,x1是k+1-x的因数,只能是奇数,此时Bob 占有它,k+1-x-x1为偶数且小于k,相当于Alice偶数先手,Bob处于必败态,则 Alice 处于必胜态。

所以猜想成立。

根据题目都是Alice先手

🌈代码实现

def divisorGame(n):
    return n % 1 == 0

或者 

def divisorGame(n):
    return n & 1 == 0

这两种写法都是判断n是否为偶数,第一种写法使用求模运算,第二种方法使用位运算。两种写法时间空间复杂度都是O(1)。不过第二种写法理论来说运算速度更快。

了解位运算:还在为原码、反码、补码和位运算搞得头昏脑涨?点这里,还你清析脑回路

🌟解法二:

我们按照游戏规则进行。

 🌈代码实现

def divisorGame(n):
    dp = []
    x = 1
    flag = False
    while x < n + 1:
        if n % x == 0:
            n -= x
            dp.append(flag)
            flag = not flag
            x = 1
        else:
            x += 1
    return dp[-1]

✏代码注释 

def divisorGame(n):
    dp = []  # 用于储存游戏结果
    x = 1    # Alice先手最小取1
    flag = False  # 初始化标记值
    while x < n + 1:
        if n % x == 0:
            n -= x
            dp.append(flag)
            """轮到Bob的回合,说明Alice成功找到符合游戏规则的x,
            我们将flag = False变成True,当Bob也从1开始寻找满足的x,
            当Bob找到符合的x后,轮到Alic,这时将flag = True换成flag = False。
            由此可以看出当下一个人找不到满足的x时,对应dp中的最后一个元素满足题意"""
            flag = not flag  
            x = 1
        else:
            x += 1   # 所取的x不满足游戏规则,需要提高x的值
    return dp[-1]

今天就到这,明天见。🚀

❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄end❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄❄

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亖夕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值