问题描述
小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
关键点
配对规则: 如果队伍数为偶数,每支队伍都会与另一支队伍配对,进行 n / 2 场比赛,剩下 n / 2 支队伍。 如果队伍数为奇数,会随机轮空并晋级一支队伍,其余的队伍配对,进行 (n - 1) / 2 场比赛,剩下 (n - 1) / 2 + 1 支队伍。 递归思想: 每次配对后,队伍数会减少,直到剩下1支队伍为止。 每次配对都会产生新的队伍数,继续进行配对,直到队伍数为1。
解题思路
-
递归函数:
- 设计一个递归函数
solution(n),表示从n支队伍开始,直到决出唯一获胜队伍为止,总共进行的配对次数。 - 如果
n为1,直接返回0,因为不需要进行任何配对。 - 如果
n为偶数,返回n / 2加上solution(n / 2)。 - 如果
n为奇数,返回(n - 1) / 2加上solution((n - 1) / 2 + 1)。
- 设计一个递归函数
-
迭代方法:
- 也可以使用迭代方法,每次根据当前队伍数计算配对次数,直到队伍数为1。
最终代码(以cpp为例)
#include <bits/stdc++.h>
using namespace std;
int solution(int n) { // write code here return n-1; }
int main() {
cout << (solution(7) == 6) << endl;
cout << (solution(14) == 13) << endl;
cout << (solution(1) == 0) << endl;
return 0;
}
总结
通过递归或迭代的方式,可以计算出从 n 支队伍开始,直到决出唯一获胜队伍为止。