华为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和Nif (!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>() {@Overridepublic 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) {// 捕获任何异常,输出-1System.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在线答疑。