查找配对次数问题|豆包MarsCode AI 刷题

42 阅读3分钟

问题描述

小R正在组织一场比赛,比赛中有 n 支队伍参赛。比赛采用如下赛制:

  1. 偶数队伍时:每支队伍配对,总共进行 n / 2 场比赛,获胜的 n / 2 支队伍晋级下一轮。
  2. 奇数队伍时:随机轮空一支队伍直接晋级,剩下的队伍进行 (n - 1) / 2 场比赛,最终有 (n - 1) / 2 + 1 支队伍进入下一轮。

比赛继续进行,直到决出唯一的获胜队伍为止。请计算在整场比赛中,一共进行了多少场配对比赛


输入输出格式

输入

  • 一个整数 n,表示参赛队伍的数量。

输出

  • 返回一个整数,表示进行的配对总次数。

参数限制

  • 1 <= n <= 10^9

测试样例

样例 1

输入:n = 7
输出:6
解释

  • 第一轮:7 是奇数,轮空 1 支,进行 (7 - 1) / 2 = 3 场比赛。剩余 4 支队伍晋级。
  • 第二轮:4 是偶数,进行 4 / 2 = 2 场比赛。剩余 2 支队伍晋级。
  • 第三轮:2 是偶数,进行 2 / 2 = 1 场比赛。剩余 1 支队伍晋级。
  • 总计 3 + 2 + 1 = 6 场比赛。

样例 2

输入:n = 14
输出:13
解释

  • 第一轮:14 是偶数,进行 14 / 2 = 7 场比赛。剩余 7 支队伍晋级。
  • 第二轮:7 是奇数,轮空 1 支,进行 (7 - 1) / 2 = 3 场比赛。剩余 4 支队伍晋级。
  • 第三轮:4 是偶数,进行 4 / 2 = 2 场比赛。剩余 2 支队伍晋级。
  • 第四轮:2 是偶数,进行 2 / 2 = 1 场比赛。剩余 1 支队伍晋级。
  • 总计 7 + 3 + 2 + 1 = 13 场比赛。

样例 3

输入:n = 1
输出:0
解释:只有 1 支队伍时,无需进行任何比赛。


解题思路

  1. 按比赛规则递归计算配对次数

    • 若队伍数为偶数,直接进行 n / 2 场比赛,并更新队伍数为 n / 2
    • 若队伍数为奇数,进行 (n - 1) / 2 场比赛,更新队伍数为 (n - 1) / 2 + 1
  2. 不断进行比赛,直到只剩下 1 支队伍为止。

  3. 累计所有比赛的总次数并返回结果。


代码实现

C++ 实现

#include <iostream> using namespace std; 
int solution(int n) {
    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; 
} int main() { 
    cout << (solution(7) == 6) << endl;
            // 输出 6 cout << (solution(14) == 13) << endl; // 输出 13 cout << (solution(1) == 0) << endl; // 输出 0 return 0; 
}

ai分析:

时间复杂度

  • 每次比赛后队伍数量减少一半,最多需要 O(log n) 轮比赛。
  • 每轮比赛的计算复杂度为 O(1),因此总时间复杂度为 O(log n)

空间复杂度

  • 仅使用常量级变量存储结果,空间复杂度为 O(1)

总结

这道题通过模拟比赛过程,以 O(log n) 的时间复杂度高效计算了比赛总次数。
题目核心是对奇偶队伍数的处理,通过分情况计算更新队伍数和比赛次数,保持算法逻辑清晰简单。