问题
问题描述
小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
思路
初始化:
定义一个变量 matches 来记录总比赛场次,初始值为 0。输入队伍数 nnn。
比赛过程:
当队伍数 n>1n > 1n>1 时:
如果 nnn 是偶数:
比赛场次为 n/2n / 2n/2。下一轮的队伍数为 n/2n / 2n/2。如果 nnn 是奇数:
比赛场次为 (n−1)/2(n - 1) / 2(n−1)/2。下一轮的队伍数为 (n−1)/2+1(n - 1) / 2 + 1(n−1)/2+1。将当前轮的比赛场次累加到 matches。
终止条件:
当队伍数为 1 时停止循环,返回累积的比赛场次 matches。
示例 1:solution(7)
初始队伍数:7
第1轮:7 是奇数,进行 (7-1)/2 = 3 场比赛,剩下 3 + 1 = 4 个队伍。第2轮:4 是偶数,进行 4 / 2 = 2 场比赛,剩下 2 个队伍。第3轮:2 是偶数,进行 2 / 2 = 1 场比赛,剩下 1 个队伍(比赛结束)。总比赛场次:3 + 2 + 1 = 6 场。输出:6
示例 2:solution(14)
初始队伍数:14
第1轮:14 是偶数,进行 14 / 2 = 7 场比赛,剩下 7 个队伍。第2轮:7 是奇数,进行 (7-1)/2 = 3 场比赛,剩下 3 + 1 = 4 个队伍。第3轮:4 是偶数,进行 4 / 2 = 2 场比赛,剩下 2 个队伍。第4轮:2 是偶数,进行 2 / 2 = 1 场比赛,剩下 1 个队伍(比赛结束)。总比赛场次:7 + 3 + 2 + 1 = 13 场。输出:13
示例 3:solution(1)
初始队伍数:1,已经只有一个队伍,比赛结束,不需要进行任何比赛。
输出:0
代码
public class Main {
public static int solution(int n) {
int matches = 0; // 初始化比赛场次
while (n > 1) {
if (n % 2 == 0) {
// 偶数队伍
matches += n / 2; // 本轮比赛场次
n = n / 2; // 下一轮队伍数
} else {
// 奇数队伍
matches += (n - 1) / 2; // 本轮比赛场次
n = (n - 1) / 2 + 1; // 下一轮队伍数
}
}
return matches; // 返回总比赛场次
}
public static void main(String[] args) {
// 测试样例
System.out.println(solution(7)); // 输出 6
System.out.println(solution(14)); // 输出 13
System.out.println(solution(1)); // 输出 0
}
}
solution 方法:
该方法接受一个参数 n,表示参赛队伍的总数。matches 用于记录比赛的总场次,初始值为0。使用 while (n > 1) 循环,直到队伍数 n 小于或等于1为止,每次循环模拟一轮比赛。
判断 n 的奇偶性:
如果队伍数 n 为偶数(即 n % 2 == 0),则直接进行 n / 2 场比赛,所有队伍都能分成一对一的比赛。
比赛后,队伍数 n 减少为 n / 2,即进入下一轮。如果队伍数 n 为奇数(即 n % 2 != 0),则进行 (n - 1) / 2 场比赛,剩下一个队伍直接晋级到下一轮。
比赛后,队伍数变为 (n - 1) / 2 + 1,即上一轮晋级的队伍数量。
返回结果:
当队伍数变为1时,退出循环,返回总的比赛场次。提交结果