3、射击比赛——华子机试必知必会

208 阅读1分钟

题目描述

给定一个射击比赛成绩单,包含多个选手若干次射击的成绩分数,请对每个选手按其最高三个分数之和进行降序排名,输出降序排名后的选手ID序列

条件如下:

  1. 一个选手可以有多个射击成绩的分数 且次序不固定
  2. 如果一个选手成绩小于三个 则认为选手的所有成绩无效 排名忽略该选手
  3. 如果选手的成绩之和相等,则成绩相等的选手按照其ID降序排列

输入描述

输入第一行:一个整数 N表示该场比赛总共进行了N次射击,产生N个成绩分数 2 <= N <= 100
输入第二行:一个长度为N的整数序列,表示参与本次射击的选手Id 0 <= ID <= 99
输入第三行:一个长度为N的整数序列,表示参与每次射击的选手对应的成绩 0 <= 成绩 <= 100

输出描述

符合题设条件的降序排名后的选手ID序列

示例一

输入

13
3,3,7,4,4,4,4,7,7,3,5,5,5
53,80,68,24,39,76,66,16,100,55,53,80,55

输出

5,3,7,4

说明

该场射击比赛进行了13次,参赛选手为3 4 5 7
3号选手的成绩为53 80 55最高三个成绩的和为 188
4号选手的成绩为24 39 76 66最高三个和为181
5号选手的成绩为53 80 55 最高三个和为188
7号选手成绩为68 16 100 最高三个和184
比较各个选手最高三个成绩的和
3 = 5 > 7 > 4
由于35成绩相等 且5 > 3 所以输出为5,3,7,4

解题方法

public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入比赛总场数:");
        int N = scanner.nextInt();
        scanner.nextLine();
        System.out.println("请输入参与各场射击的选手Id:");
        String[] idsStr = scanner.nextLine().split(",");
        System.out.println("请输入参与各场射击的选手的成绩:");
        String[] scoresStr = scanner.nextLine().split(",");
        Map<Integer, List<Integer>> scoresMap = new HashMap<>();
        for (int i = 0; i < N; i++) {
            int id = Integer.parseInt(idsStr[i]);
            int score = Integer.parseInt(scoresStr[i]);
            scoresMap.putIfAbsent(id, new ArrayList<>());
            scoresMap.get(id).add(score);
        }

        List<Integer> result = new ArrayList<>();
        for (Map.Entry<Integer, List<Integer>> entry : scoresMap.entrySet()) {
            List<Integer> scores = entry.getValue();
            //将分数值先按照降序排列,方便找到最高三数之和
            Collections.sort(scores, Collections.reverseOrder());
            scoresMap.put(entry.getKey(),scores);
            result.add(entry.getKey());
        }

        Collections.sort(result, new Comparator<Integer>() {
            @Override
            public int compare(Integer id1, Integer id2) {
                List<Integer> scores1 = scoresMap.get(id1);
                List<Integer> scores2 = scoresMap.get(id2);
                int sum1 = 0;
                int sum2 = 0;
                for (int i = 0; i < Math.min(scores1.size(), 3); i++) {
                    sum1 += scores1.get(i);
                }
                for (int i = 0; i < Math.min(scores2.size(), 3); i++) {
                    sum2 += scores2.get(i);
                }
                if (sum1 == sum2) {
                    return id2 - id1; // 按ID降序排列
                }
                return sum2 - sum1; // 按成绩之和降序排列
            }
        });

        StringBuilder output = new StringBuilder();
        for (int i = 0; i < result.size(); i++) {
            if (i > 0) {
                output.append(",");
            }
            output.append(result.get(i));
        }

        System.out.println(output.toString());
    }

华为OD机试 | AmosCloud Wiki