比赛配对问题 | 豆包MarsCode AI 刷题

103 阅读3分钟

比赛配对问题练习笔记

问题分析

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

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

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

问题分析

这道题描述了一个比赛的赛制,要求我们计算总共的配对次数,直到剩下唯一的获胜队伍。赛制规则分为以下两种情况:

  1. 偶数队伍:如果当前参赛队伍数是偶数,每两队进行一场比赛,产生 n / 2 支队伍进入下一轮。
  2. 奇数队伍:如果当前参赛队伍数是奇数,则有一支队伍自动晋级,其余队伍进行配对。总共进行 (n - 1) / 2 场比赛,产生 (n - 1) / 2 + 1 支队伍进入下一轮。

每轮比赛都减少了一部分队伍,直到最终决出唯一的获胜队伍。题目要求输出所有配对次数的总和。

题目等级

难度:简单

解题思路

这道题的核心在于模拟每一轮比赛的过程,并累计总的配对次数。

  1. 初始化计数器:我们定义一个变量 total_matches 来累计所有的配对次数。
  2. 循环比赛过程:每轮根据队伍数的奇偶性计算当前轮次的配对次数,并更新剩余队伍数。
    • 如果队伍数为偶数:进行 n / 2 场比赛,然后进入下一轮的队伍数更新为 n / 2
    • 如果队伍数为奇数:进行 (n - 1) / 2 场比赛,自动晋级一支队伍,进入下一轮的队伍数为 (n - 1) / 2 + 1
  3. 终止条件:循环继续,直到只剩下一个队伍(即最终获胜者),此时比赛结束。

这个方法的时间复杂度为 O(log n),因为每一轮队伍数几乎减半,效率较高。

代码实现

我直接通过判断奇偶性来计算每轮的比赛次数和剩余队伍数。以下是具体的实现:

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  # 一支队伍轮空,剩余的队伍数为 (n-1)//2 + 1
    return total_matches

测试

通过几个测试用例来验证代码的正确性:

# 测试
print(solution(7))  # 输出: 6
print(solution(14))  # 输出: 13
print(solution(1))  # 输出: 0
  • 样例 1n = 7

    • 轮次 1:配对 (7 - 1) / 2 = 3 场,总配对数为 3,剩下 4 支队伍。
    • 轮次 2:配对 4 / 2 = 2 场,总配对数累计 5,剩下 2 支队伍。
    • 轮次 3:配对 2 / 2 = 1 场,总配对数累计 6,只剩下 1 支队伍,比赛结束。
    • 最终输出为 6
  • 样例 2n = 14

    • 轮次 1:配对 14 / 2 = 7 场,总配对数为 7,剩下 7 支队伍。
    • 轮次 2:配对 (7 - 1) / 2 = 3 场,总配对数累计 10,剩下 4 支队伍。
    • 轮次 3:配对 4 / 2 = 2 场,总配对数累计 12,剩下 2 支队伍。
    • 轮次 4:配对 2 / 2 = 1 场,总配对数累计 13,只剩下 1 支队伍,比赛结束。
    • 最终输出为 13
  • 样例 3n = 1

    • 由于只有一支队伍,比赛直接结束,输出为 0

小结

这个问题是一个经典的模拟问题,主要考察如何设计循环和条件判断来逐步减少队伍数。通过对队伍数的奇偶判断,可以轻松实现每轮的配对过程并累计总的配对次数。