文科生勇闯ai刷题20. 比赛配对问题 | 豆包MarsCode AI刷题

61 阅读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

MarsCode代码提示

问题理解

你需要计算在比赛中进行的配对次数,直到决出唯一的获胜队伍为止。比赛遵循以下规则:

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

数据结构选择

这个问题不需要复杂的数据结构,只需要一个整数来表示当前的队伍数。

算法步骤

  1. 边界条件

    • 如果当前队伍数为 1,则不需要进行任何配对,直接返回 0
  2. 配对次数计算

    • 如果当前队伍数为偶数,计算当前轮的配对次数为 n // 2,并且下一轮的队伍数为 n // 2
    • 如果当前队伍数为奇数,计算当前轮的配对次数为 (n - 1) // 2,并且下一轮的队伍数为 (n - 1) // 2 + 1
  3. 递归调用

    • 递归计算下一轮的配对次数,直到队伍数为 1

总结

  • 使用递归方法来计算每一轮的配对次数。
  • 确保递归调用的参数正确,即根据当前队伍数是奇数还是偶数来选择正确的下一轮队伍数。
  • 确保递归终止条件是正确的,即当队伍数为 1 时返回 0
def solution(n: int) -> int:
    # 边界条件:如果只剩下一个队伍,不需要进行任何配对
    if n == 1:
        return 0
    
    # 计算当前轮的配对次数
    if n % 2 == 0:
        pairs = n // 2
        next_round_teams = n // 2  # 提示:偶数队伍时,下一轮的队伍数
    else:
        pairs = (n - 1) // 2
        next_round_teams = (n - 1) // 2 + 1  # 提示:奇数队伍时,下一轮的队伍数
    
    # 递归计算下一轮的配对次数
    return pairs + solution(next_round_teams)  # 提示:使用正确的下一轮队伍数

if __name__ == '__main__':
    print(solution(7) == 6)
    print(solution(14) == 13)
    print(solution(1) == 0)
    

知识点总结

  1. 递归(Recursion)

    • 递归是解决这个问题的核心方法。通过递归调用,我们可以逐步减少队伍数,直到只剩下一个队伍为止。
    • 递归函数需要有明确的终止条件,即当队伍数为 1 时返回 0
  2. 条件判断(Conditional Statements)

    • 使用 if-else 语句来判断当前队伍数是奇数还是偶数,并根据判断结果计算当前轮的配对次数和下一轮的队伍数。
  3. 整数除法和取模运算(Integer Division and Modulo Operation)

    • 使用 // 进行整数除法,计算当前轮的配对次数和下一轮的队伍数。
    • 使用 % 进行取模运算,判断当前队伍数是奇数还是偶数。
  4. 函数定义和调用(Function Definition and Call)

    • 定义一个函数 solution(n) 来计算配对次数。
    • 在函数内部调用自身来实现递归。
  5. 边界条件处理(Edge Case Handling)

    • 处理边界条件,即当队伍数为 1 时,直接返回 0,因为不需要进行任何配对。