一、题目描述

一个有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、打分不在范围内。

四、解题思路

题目要求计算得分最多的3位选手的编号,评委打分范围为1到10分,选手数量和评委数量在给定范围内。

我们可以使用一个自定义的Player类来表示选手,其中包含选手的编号、总分和每个评委的打分列表。首先,我们需要读取输入的评委数量和选手数量,并进行合法性校验。然后,读取每个评委对每个选手的打分,将评分信息存储在列表中。接下来,根据评分信息计算每个选手的总分,并创建Player对象存储选手信息。最后,按照题目要求进行排序,输出得分最高的3位选手的编号。

  1. 读取输入的评委数量和选手数量,进行合法性校验。如果不满足条件,直接输出-1并结束程序;
  2. 使用一个列表存储每个评委对每个选手的打分。遍历评委列表,读取每个评委对每个选手的打分,将打分信息存储在列表中;
  3. 创建一个空列表playerList,用于存储选手信息;
  4. 遍历选手列表,计算每个选手的总分,同时将每个选手的打分列表存储在playerList中;
  5. 实现Player类,包含选手的编号、总分和打分列表。在Player类中,实现Comparable接口,根据题目要求重写compareTo方法,按照总分和最高分数量进行排序;
  6. 使用Collections.sort对playerList进行排序;
  7. 输出得分最高的3位选手的编号,按照题目要求输出。

该算法通过读取评委和选手的打分信息,计算每个选手的总分,并按照总分和最高分数量进行排序,输出得分最高的3位选手的编号。算法的时间复杂度主要取决于排序的时间复杂度,为O(NlogN),其中N为选手的数量。

五、Java算法源码

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    String[] num = sc.nextLine().split(",");
    int judges = Integer.parseInt(num[0]);//评委
    int player = Integer.parseInt(num[1]);//选手

    // 硬性规则校验
    if (judges > 10 || judges < 3 || player > 100 || player < 3) {
        System.out.println(-1);
        return;
    }

    List<String[]> list = new ArrayList<>();
    for (int i = 0; i < judges; i++) {
        list.add(sc.nextLine().split(","));
    }

    // 收集选手信息
    List<Player> playerList = new ArrayList<>();
    // 遍历选手
    for (int i = 0; i < player; i++) {
        int total = 0;
        List<Integer> scoreList = new ArrayList<>();
        // 遍历评委
        for (int j = 0; j < judges; j++) {
            String[] arr = list.get(j);
            // 评委的评分
            int score = Integer.parseInt(arr[i]);
            if (score < 0 || score > 10) {
                System.out.println(-1);
                return;
            }
            scoreList.add(score);
            total += score;
        }
        playerList.add(new Player(i, total, scoreList));
    }

    // 比较选手分数
    Collections.sort(playerList);
    for (int i = 0; i < 3; i++) {
        if (i == 2) {
            System.out.println(playerList.get(i).index + 1);
        } else {
            System.out.print(playerList.get(i).index + 1 + ",");
        }
    }

}

private static class Player implements Comparable<Player> {
    private int index;
    private int total;
    private List<Integer> scores;

    public Player(int index, int total, List<Integer> scores) {
        this.index = index;
        this.total = total;
        this.scores = scores;
    }

    private int checkCount(List<Integer> list, int count) {
        int ret = 0;
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i) == count) {
                ret++;
            }
        }
        return ret;
    }

    @Override
    public int compareTo(Player player) {
        // 比较总分
        if (player.total < this.total) {
            return -1;
        } else if (player.total > this.total) {
            return 1;
        } else {
            // 比较最高分的数量
            List<Integer> playerList = player.scores;
            List<Integer> scoreList = this.scores;
            for (int i = 10; i > 0; i--) {
                int ipl = checkCount(playerList, i);
                int ith = checkCount(scoreList, i);
                if (ipl < ith) {
                    return -1;
                }
            }
        }
        return 0;
    }
}

六、效果展示

华为OD机试真题 Java 实现【比赛评分】【2023 B卷 100分】,附详细解题思路-LMLPHP


🏆下一篇:华为OD机试真题 Java 实现【跳房子II】【2023 B卷 100分】,附详细解题思路

🏆本文收录于,华为OD机试(JAVA)(2022&2023)

每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。

华为OD机试真题 Java 实现【比赛评分】【2023 B卷 100分】,附详细解题思路-LMLPHP

06-04 21:26