问题描述
小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
求解思路
要解决这个问题,我们需要模拟比赛的过程,直到只剩下一支队伍。每一轮比赛中,根据当前队伍数的奇偶性,计算出本轮比赛的配对次数,并更新剩余队伍数。具体步骤如下:
- 初始化总配对次数:首先,我们需要一个变量来记录总配对次数,将其初始化为0。
- 循环进行比赛:当队伍数大于1时,进入循环:
• 偶数情况:如果当前队伍数为偶数,计算本轮比赛的配对次数为 n / 2,并更新剩余队伍数为 n / 2。
• 奇数情况:如果当前队伍数为奇数,计算本轮比赛的配对次数为 (n - 1) / 2,并更新剩余队伍数为 (n - 1) / 2 + 1。
- 累加配对次数:将本轮比赛的配对次数累加到总配对次数中。
- 返回结果:循环结束后,返回总配对次数。
详细解释
- 初始化: • 我们首先初始化一个变量来记录总配对次数,例如 totalMatches = 0。
- 循环条件: • 使用 while (n > 1) 作为循环条件,当队伍数大于1时,继续循环。
- 偶数情况: • 使用 if (n % 2 == 0) 判断当前队伍数是否为偶数。
• 如果是偶数,计算本轮比赛的配对次数为 n / 2,并将其累加到总配对次数中。
• 更新剩余队伍数为 n / 2。
- 奇数情况: • 使用 else 处理当前队伍数为奇数的情况。
• 计算本轮比赛的配对次数为 (n - 1) / 2,并将其累加到总配对次数中。
• 更新剩余队伍数为 (n - 1) / 2 + 1。
- 返回结果: • 循环结束后,返回总配对次数 totalMatches。
具体代码
public static int solution(int n) {
int totalMatches = 0;
while (n > 1) {
if (n % 2 == 0) {
totalMatches += n / 2;
n = n / 2;
} else {
totalMatches += (n - 1) / 2;
n = (n - 1) / 2 + 1;
}
}
return totalMatches;
}
public static void main(String[] args) {
System.out.println(solution(7) == 6);
System.out.println(solution(14) == 13);
System.out.println(solution(1) == 0);
}
}
题目总结
通过上述分析和实现,我们可以清晰地看到,问题的核心在于模拟比赛的过程,并根据当前队伍数的奇偶性来计算每轮比赛的配对次数。最终,我们累加所有轮次的配对次数,得到总的比赛场次。这个方法的时间复杂度为 O(log n),因为每轮比赛后队伍数大约减半,效率较高,适用于较大的 n 值。