问题描述
小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
算法思路
这个问题实际上是一个关于递归和数学的问题。我们需要计算在每一轮比赛中进行的配对次数,直到只剩下一支队伍。我们可以观察到,每一轮比赛后,队伍的数量会减少一半(如果队伍数为偶数)或者减少一半再加一(如果队伍数为奇数)。这个过程会一直持续,直到只剩下一支队伍。
构建一个数组num_per_round[ ]存放每轮比赛结束后剩余的人数
如果剩余人数为1,无法继续配对,比赛结束
num_per_round[0] = n
num_per_round[1] = int(num_per_round[0]) - int(num_per_round[0] / 2)
num_per_round[2] = int(num_per_round[1]) - int(num_per_round[1] / 2)
……
最后遍历数组,用第i轮的比赛人数与第i - 1轮的比赛人数相减即为这一轮的比赛轮次,累加即可得到最终结果
算法执行流程
样例1:n = 7
第 1 轮比赛后剩下 4 支队伍,进行了 3 场比赛
第 2 轮比赛后剩下 2 支队伍,进行了 2 场比赛
第 3 轮比赛后剩下 1 支队伍,进行了 1 场比赛
总共进行了 6 场比赛
样例2: n = 14
第 1 轮比赛后剩下 7 支队伍,进行了 7 场比赛
第 2 轮比赛后剩下 4 支队伍,进行了 3 场比赛
第 3 轮比赛后剩下 2 支队伍,进行了 2 场比赛
第 4 轮比赛后剩下 1 支队伍,进行了 1 场比赛
总共进行了 13 场比赛
样例3: n = 1
总共进行了 0 场比赛
Solution
class Main {
public static int solution(int n) {
int[] num_per_round = new int[100];
num_per_round[0] = n;
for (int i = 1; i < 100; i++) {
if (num_per_round[i - 1] == 1) {
break;
}
num_per_round[i] = (num_per_round[i - 1] % 2 == 0) ? (num_per_round[i - 1] / 2)
: (num_per_round[i - 1] / 2 + 1);
}
int res = 0;
for (int j = 1; j < 100; j++) {
if (num_per_round[j - 1] == 1) {
break;
}
res += num_per_round[j - 1] - num_per_round[j];
}
return res;
}
public static void main(String[] args) {
System.out.println(solution(7));
System.out.println(solution(14));
System.out.println(solution(1));
}
}
// 递归法
public class Solution {
public int numberOfMatches(int n) {
// 如果只有一支队伍,不需要比赛
if (n <= 1) {
return 0;
}
// 如果队伍数为偶数,每轮比赛后队伍数减半
// 如果队伍数为奇数,每轮比赛后队伍数减半再加一
// 因此,每轮比赛的配对次数为 n/2 (向下取整)
return (n / 2) + numberOfMatches(n / 2 + n % 2);
}
public static void main(String[] args) {
Solution solution = new Solution();
System.out.println(solution.numberOfMatches(7)); // 输出:6
System.out.println(solution.numberOfMatches(14)); // 输出:13
System.out.println(solution.numberOfMatches(1)); // 输出:0
}
}