题目描述
有N(3 ≤ N < 10000)
个运动员,他们的 id
为 0
到 N-1
,他们的实力由一组整数表示。他们之间进行比赛,需要决出冠亚军。比赛的规则是 0 号和 1 号比赛,2 号和 3 号比赛,以此类推,每一轮,相邻的运动员进行比赛,获胜的进入下一轮;实力值大的获胜,实力值相等的情况,id
小的情况下获胜;轮空的直接进入下一轮。
输入描述
输入一行N
个数字代表N的运动员的实力值,0 <= 实力值 <= 10000000000
。
输出描述
输出冠亚季军的id
,用空格隔开。
用例1
输入:2 3 4 5
输出:3 1 2
说明:第一轮比赛,id 为 0 实力值为 2 的运动员和 id 为 1 实力值为 3 的运动员比赛,1号胜出进入下一轮争夺冠亚军;id 为 2 的运动员和 id 为 3 的运动员比赛,3 号胜出进入下一轮争夺冠亚军,冠亚军比赛,3 号胜 1 号,故冠军为 3 号,亚军为 1 号,2 号与 0 号,比赛进行季军的争夺,2 号实力值为 4,0 号实力值 2,故 2 号胜出,得季军。冠亚季军为 3 1 2。
题解
- 输入处理:
- 读取一行输入并分割为字符串数组
- 为每个运动员创建包含实力值和
ID
的数组
- 比赛模拟:
- 使用循环模拟每轮比赛,直到决出冠军
- 计算下一轮选手数量,判断当前轮是否为半决赛
- 遍历当前选手,两两进行比赛:
- 实力值高者获胜(实力相等时
ID
小者获胜) - 半决赛淘汰者加入季军候选人
- 决赛轮记录亚军
- 实力值高者获胜(实力相等时
- 结果确定:
- 最后剩下的选手为冠军
- 亚军已在决赛轮记录
- 季军由半决赛淘汰者中最强者获得
- 输出结果:
- 按格式输出冠军、亚军和季军的
ID
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] input = sc.nextLine().split(" ");
int n = input.length;
// 创建选手列表,每个元素是[实力值, id]的数组
List<long[]> players = new ArrayList<>();
for (int i = 0; i < n; i++) {
players.add(new long[]{Long.parseLong(input[i]), i});
}
// 存储半决赛淘汰的选手(季军候选人)
List<long[]> thirdCandidates = new ArrayList<>();
long[] runnerUp = null; // 亚军
// 模拟比赛过程
while (players.size() > 1) {
int size = players.size();
int nextSize = (size + 1) / 2; // 计算下一轮人数
boolean isSemiFinal = (nextSize == 2); // 判断是否为半决赛轮
List<long[]> nextRound = new ArrayList<>(); // 晋级下一轮的选手
// 遍历当前轮选手,两两比赛
for (int i = 0; i < size; i += 2) {
if (i + 1 < size) { // 正常比赛
long[] a = players.get(i);
long[] b = players.get(i + 1);
// 比较两个选手,返回正数表示a更强,负数表示b更强
int cmp = compare(a, b);
long[] winner = cmp > 0 ? a : b; // 胜者
long[] loser = cmp > 0 ? b : a; // 败者
// 半决赛轮记录淘汰者
if (isSemiFinal) thirdCandidates.add(loser);
// 决赛轮记录亚军
if (size == 2) runnerUp = loser;
nextRound.add(winner);
} else { // 轮空选手直接晋级
nextRound.add(players.get(i));
}
}
players = nextRound; // 更新为下一轮选手
}
// 最后剩下的选手是冠军
long[] champion = players.get(0);
// 确定季军:半决赛淘汰者中最强的
long[] third = thirdCandidates.size() == 1 ?
thirdCandidates.get(0) :
compare(thirdCandidates.get(0), thirdCandidates.get(1)) > 0 ?
thirdCandidates.get(0) : thirdCandidates.get(1);
// 输出冠亚季军的id
System.out.println(champion[1] + " " + runnerUp[1] + " " + third[1]);
}
// 比较两个选手的方法
// 返回值:正数表示a更强,负数表示b更强
private static int compare(long[] a, long[] b) {
// 先比较实力值
if (a[0] != b[0]) {
return Long.compare(a[0], b[0]);
}
// 实力值相等时,id小的更强(注意:返回b[1]-a[1]的逆序)
return Long.compare(b[1], a[1]);
}
}