青训营X豆包MarsCode 技术训练营第一课 | 豆包MarsCode AI 刷题

24 阅读3分钟

比赛配对问题:

问题描述

小R正在组织一个比赛,比赛中有 n 支队伍参赛。比赛遵循以下独特的赛制:

  • 如果当前队伍数为 偶数,那么每支队伍都会与另一支队伍配对。总共进行 n / 2 场比赛,且产生 n / 2 支队伍进入下一轮。
  • 如果当前队伍数为 奇数,那么将会随机轮空并晋级一支队伍,其余的队伍配对。总共进行 (n - 1) / 2 场比赛,且产生 (n - 1) / 2 + 1 支队伍进入下一轮。

小R想知道在比赛中进行的配对次数,直到决出唯一的获胜队伍为止。

我的代码:

def solution(n: int) -> int:
    total_matches = 0  # 初始化配对次数
    while n > 1:  # 直到只剩下一个队伍
        if n % 2 == 0:
            total_matches += n // 2  # 偶数情况
            n = n // 2  # 进入下一轮的队伍数
        else:
            total_matches += (n - 1) // 2  # 奇数情况
            n = (n - 1) // 2 + 1  # 进入下一轮的队伍数
    return total_matches

if __name__ == '__main__':
    # 测试用例
    print(solution(7) == 6)  # 输出应为 6
    print(solution(14) == 13)  # 输出应为 13
    print(solution(1) == 0)  # 输出应为 0
    # 任意输入输出
    print(solution(10))  # 可以输出其他任意 n 的结果
    print(solution(20))  # 输出应为 19
    print(solution(3))   # 输出应为 2

思路详解: 这道题目本质上是一个关于数学归纳和递归规律的逻辑问题,核心是通过比赛规则对队伍数的变化进行逐步分析,最终找到比赛总的配对次数。这其中涉及了两个主要的规则:奇数队伍的处理方式和偶数队伍的处理方式,并通过逐轮的迭代完成最终的计算。在解题的过程中,不仅可以更好地理解数学和编程的结合,也可以体会到如何用清晰的逻辑和代码解决实际问题。

递减规律与终止条件: 这道题的一个关键是“递减”。每一轮比赛都会使得队伍数量减少约一半,无论当前是奇数还是偶数,最终的递归或循环都会在 n=1 时结束。对这一过程的抽象化理解可以帮助我们用更高效的方式实现代码。这其实也体现了一种分治思想:每次将问题规模缩小一半,最终聚焦于一个最小规模的问题。

奇偶性对计算的影响: 一个有趣的地方在于,奇数队伍的处理方式需要额外关注“轮空”的情况。每次轮空会导致队伍数少减一支,同时对总配对次数的计算也会稍显不同。正是这些细微差别,构成了这道题目中需要我们理解和处理的重点。因此,编写代码时,必须明确两种情况下的逻辑分支,确保不会遗漏任何特殊情况。

编程的启示和总结: 写这道题目也让我意识到,在实际编程中,逻辑的清晰性和代码的简洁性同样重要。尤其是在处理类似奇偶分支的问题时,尽可能减少重复逻辑,使代码更具通用性和可读性。此外,通过不断优化逻辑,可以让代码更高效,也更容易扩展到其他应用场景。这道题目不仅仅是一道逻辑题,更是一种编程思想的实践。通过分析队伍的奇偶性,我们归纳出其递减规律,并利用分治思想逐步解决问题。在解决问题的过程中,我们还可以体会到数学和计算机科学的结合带来的乐趣。这种题目虽然表面简单,但其背后蕴含的逻辑和抽象思维值得我们深入思考和总结。这种思考过程不仅有助于提高编程能力,也能激发我们对更复杂问题的兴趣和探索欲。