华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(E卷+D卷+A卷+B卷+C卷)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
一个有N个选手参加的比赛,选手编号为1~N(3 <= N <= 100),有M(3 <= M <= 10)个评委对选手进行打分。
打分规则为每个评委对选手打分,最高为10分,最低为1分。
请计算得分最多的3位选手的编号。
如果得分相同,得分高分值最多的选手排名靠前。
(10分数量相同,则比较9分的数量,以此类推,用例中不会出现多个选手得分完全相同的情况。)
二、输入描述
第一行为半角逗号分割的两个正整数,第一个数字表示M(3 <= M <= 10)个评委,第二个数字表示N(3 <= N <= 100)个选手。
第2到M+1行为半角逗号分割的整数数组,表示评委对每个选手的打分,0号下标数字表示1号选手分数,1号下标数字表示2号选手分数,依次类推。
三、输出描述
选手前3名的编号。
注意:
若输入为异常,输出-1,如M、N、打分不在生范围内。
四、测试用例
测试用例1:
1、输入
4,5
10,6,9,7,6
9,10,6,7,5
8,10,6,5,10
9,10,8,4,9
2、输出
2,1,5
3、说明
第一行代表有4个评委,5个选手参加比赛 矩阵代表是4*5,每个数字是选手的编号,每一行代表一个评委对选手的打分排序, 2号选手得分36分排第1,1号选手36分排第2,5号选手30分(2号10分值有3个,1号10分值只有1个,所以2号排第一)
测试用例2:
1、输入
2,5
7,3,5,4,2
8,5,4,4,3
2、输出
-1
3、说明
只有2个评委,要求最少为3个评委
五、解题思路
- 遍历每个评委的打分,将每个选手的分数累加到 totalScore 中,并更新相应的 scoreCounts。
- 总得分从高到低。
- 若总得分相同,比较10分的数量,数量多的排名靠前;若10分数量相同,比较9分的数量,以此类推。
- 取排序后的前3个选手的 id,用逗号分隔输出。
- 如果输入不满足题目要求的格式或范围,直接输出 -1。
六、Java算法源码
public class OdTest01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
// 读取第一行并解析M和N
if (!scanner.hasNextLine()) {
System.out.println("-1");
return;
}
String firstLine = scanner.nextLine().trim();
String[] mn = firstLine.split(",");
if (mn.length != 2) { // 确保有两个数字
System.out.println("-1");
return;
}
int M = Integer.parseInt(mn[0].trim());
int N = Integer.parseInt(mn[1].trim());
// 验证M和N的范围
if (M < 3 || M > 10 || N < 3 || N > 100) {
System.out.println("-1");
return;
}
// 初始化选手列表
List<Contestant> contestants = new ArrayList<>();
for (int i = 1; i <= N; i++) {
contestants.add(new Contestant(i));
}
// 读取M行打分
for (int i = 0; i < M; i++) {
if (!scanner.hasNextLine()) { // 如果打分行不足M行
System.out.println("-1");
return;
}
String scoreLine = scanner.nextLine().trim();
String[] scoresStr = scoreLine.split(",");
if (scoresStr.length != N) { // 每行必须有N个分数
System.out.println("-1");
return;
}
for (int j = 0; j < N; j++) {
int score = Integer.parseInt(scoresStr[j].trim());
// 验证分数范围
if (score < 1 || score > 10) {
System.out.println("-1");
return;
}
contestants.get(j).addScore(score); // 为对应选手添加分数
}
}
// 确保没有多余的打分行
// 可以选择忽略,或进一步验证,视具体需求
// 排序选手
Collections.sort(contestants, new Comparator<Contestant>() {
@Override
public int compare(Contestant c1, Contestant c2) {
if (c2.totalScore != c1.totalScore) {
return c2.totalScore - c1.totalScore; // 总得分降序
}
// 如果总得分相同,比较分数分布
for (int i = 0; i < 10; i++) { // 从10分到1分
if (c2.scoreCounts[i] != c1.scoreCounts[i]) {
return c2.scoreCounts[i] - c1.scoreCounts[i]; // 分数数量降序
}
}
return 0; // 如果完全相同,保持原有顺序(题目保证不会有完全相同的情况)
}
});
// 取前3名
List<Integer> top3 = new ArrayList<>();
for (int i = 0; i < 3; i++) {
top3.add(contestants.get(i).id);
}
// 输出结果,用逗号分隔
StringBuilder sb = new StringBuilder();
for (int i = 0; i < top3.size(); i++) {
sb.append(top3.get(i));
if (i != top3.size() - 1) {
sb.append(",");
}
}
System.out.println(sb.toString());
} catch (Exception e) {
// 捕获任何异常,输出-1
System.out.println("-1");
} finally {
scanner.close(); // 关闭扫描器
}
}
}
// 定义选手类,包含编号、总得分和分数分布
class Contestant {
int id; // 选手编号
int totalScore; // 总得分
int[] scoreCounts; // 分数分布,scoreCounts[0]表示10分的数量,scoreCounts[9]表示1分的数量
public Contestant(int id) {
this.id = id;
this.totalScore = 0;
this.scoreCounts = new int[10]; // 初始化分数分布数组
}
// 方法:添加一个分数
public void addScore(int score) {
this.totalScore += score; // 累加总得分
if (score >=1 && score <=10) {
this.scoreCounts[10 - score] += 1; // 更新对应分数的数量
}
}
}
七、效果展示
1、输入
4,2
8,5
5,6
10,4
8,9
2、输出
-1
3、说明
只有2个评委,要求最少为3个评委
🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 E卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(E卷+D卷+A卷+B卷+C卷)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。