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

51 阅读3分钟

问题描述

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

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

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

测试样例

样例1:

输入:n = 7
输出:6

样例2:

输入:n = 14
输出:13

样例3:

输入:n = 1
输出:0

背景介绍

比赛配对问题是一个典型的递归问题,在许多比赛和竞赛中都有类似的赛制。 通过模拟比赛的各个阶段,我们能够掌握如何根据队伍数量的变化进行配对,最终直到决出一个获胜队伍为止。 类似的赛制常常出现在单败淘汰制(Elimination Tournament)中,也被广泛应用于竞技体育、游戏比赛以及其他需要从多个参与者中选出一位胜者的场景。

在这个问题中,小R组织的比赛遵循一种递进的淘汰赛制。 每轮比赛根据当前队伍的数量(奇数或偶数)进行相应的配对。 队伍配对的规则决定了每轮晋级队伍的数量,而每一轮比赛都会减少一半的队伍。 直到最后剩下唯一一支队伍为止,比赛才会结束。 我们的任务是计算从初始的队伍数量开始,每轮进行多少次配对,最终决出唯一获胜队伍所经历的配对总次数。

这个问题的本质是递归过程的模拟,类似于比赛的“二分法”进程:每一轮将队伍数目减半(或者将队伍数目减去一个并且再减半),直到最终剩下一个队伍。

解题思路

  1. 理解问题的规则
    • 当队伍数为 偶数 时,每一场比赛会有两支队伍进行配对,所以总共有 n / 2 场比赛。
    • 当队伍数为 奇数 时,其中一支队伍轮空,剩余的队伍进行配对,所以总共进行 (n - 1) / 2 场比赛,且会有一支队伍自动晋级,总共有 (n - 1) / 2 + 1 支队伍进入下一轮。
  2. 递归过程的分析 : 每一轮比赛都会减少一定数量的队伍。 可以通过递归的方式来模拟每一轮的比赛:
    • 递归终止条件 :当队伍数目变为 1 时,表示比赛结束,递归停止。
    • 递归过程 :每一轮比赛后,队伍数目减少,并且进行的配对次数累加。
  3. 计算总配对次数 : 对于每一轮:
    • 如果当前队伍数为偶数,进行 n / 2 场比赛。
    • 如果当前队伍数为奇数,进行 (n - 1) / 2 场比赛,并且有一支队伍轮空晋级。 每一轮的配对次数会累积到一个总数中,直到队伍数减少为 1 为止。
  4. 递归实现 : 使用递归函数来模拟每一轮比赛的配对过程。 在每轮中,计算当前的配对次数,递归处理剩下的队伍数。 最终,返回总的配对次数。

代码参考

def solution(n: int) -> int:
    total_matches = 0
    while n > 1:
        if n % 2 == 0:  # 如果是偶数队伍
            total_matches += n // 2
            n //= 2
        else:  # 如果是奇数队伍
            total_matches += (n - 1) // 2
            n = (n - 1) // 2 + 1
    return total_matches