小C和小M的黑板游戏 | 豆包MarsCode AI刷题

80 阅读3分钟

问题描述

小 C 和小 M 一起玩一个数字游戏,小 C 先手。在黑板上有一个初始数字 n。两人轮流操作,在每个玩家的回合中:

  1. 选择一个数字 x,要求同时满足:

    • 0<x<n
    • x 是当前数字 nn 的因数(即 n%x==0)
  2. 从当前数字 n 中减去所选的 x,得到新的数字 y=n−x

  3. 新的数字 y 将作为对手的当前数字

当一名玩家无法找到满足条件的数字 x 时,该玩家输掉游戏。

你需要判断,当小 C 和小 M 都按照最佳策略行动时,是否小 C 能够获胜。如能获胜,返回 1;否则返回 0。

解决思路

观察和分析

  1. 偶数情况

    • 如果当前数字 n 是偶数,先手玩家(小 C)可以选择 x=1,使得新的数字 y=n−1 是奇数。
    • 对手面对一个奇数时,无论选择哪个因数,新的数字都会变成偶数。
    • 这样,先手玩家总是可以在每一轮中将数字从偶数变成奇数,最终使对手面对数字 1,从而赢得游戏。
  2. 奇数情况

    • 如果当前数字 n 是奇数,先手玩家只能选择奇数 x,因为奇数的因数都是奇数。
    • 新的数字 y=n−x 仍然是偶数。
    • 对手面对一个偶数时,可以选择 x=1,使得新的数字 y=n−1 变成奇数。
    • 这样,先手玩家总是会在每一轮中将数字从奇数变成偶数,最终使自己面对数字 1,从而输掉游戏。

结论

  • 如果 n 是偶数,先手玩家(小 C)获胜,返回 1。
  • 如果 n 是奇数,先手玩家(小 C)输掉游戏,返回 0。

代码

def solution(n: int) -> int: 
    # 如果 n 是偶数,小 C 获胜,返回 1 
    # 如果 n 是奇数,小 C 输掉游戏,返回 0 
    return 1 if n % 2 == 0 else 0 
    
if __name__ == '__main__': 
    print(solution(2) == 1) # 输出: True 
    print(solution(3) == 0) # 输出: True 
    print(solution(10) == 1) # 输出: True

总结

通过解决这个问题,我深刻体会到了数学规律在算法设计中的重要性。在这个游戏中,通过观察和分析数字的奇偶性,我们找到了一个简单的数学规律,即偶数情况下先手必胜,奇数情况下先手必败。这一规律的发现,使得原本看似复杂的博弈问题得以简化为一个简单的条件判断。这不仅提高了算法的效率,也使得代码更加简洁易懂。

此外,处理边界条件也是编写健壯代码的重要一环。虽然在这个问题中,n=1n=1 显然会导致先手输掉游戏,但在实际编程中,明确处理各种边界条件有助于提高代码的鲁棒性和可维护性。例如,如果输入的 nn 是一个非常大的数,我们也需要确保算法能够在合理的时间内给出结果。

这个问题还让我意识到,许多复杂的问题往往可以通过数学分析和逻辑推理来简化。类似的方法可以应用于其他类型的博弈问题或优化问题中,帮助我们找到最优解。通过这次练习,我不仅学会了如何解决特定的问题,还提升了自己的问题分析和解决能力。这种方法论的掌握,将对我未来解决更多复杂问题提供有力的支持。