华为OD机试真题 Java 实现【比赛的冠亚季军】【2023 B卷 100分】,附详细解题思路

在这里插入图片描述

目录

    • 专栏导读
    • 一、题目描述
    • 二、输入描述
    • 三、输出描述
    • 四、解题思路
    • 五、Java算法源码
    • 六、效果展示
      • 1、输入
      • 2、输出
      • 3、说明

华为OD机试 2023B卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

  • 专栏福利:抱团取暖,群友刷题经验分享,考试经验分享。

在这里插入图片描述

一、题目描述

有个运动员,他们的id为0到N-1,他们的实力由一组整数表示。他们之间进行比赛,需要决出冠亚军。比赛的规则是0号和1号比赛,2号和3号比赛,以此类推,每一轮,相邻的运动员进行比赛,获N (3\leq N< 10000)胜的进入下一轮,实力值大的获胜,实力值相等的情况,id小的情况下获胜,轮空的直接进入下一轮。

二、输入描述

输入一行N个数字代表N的运动员的实力值。

(0 <= 实力值 <= 10000000000)。

三、输出描述

输出冠亚季军的id,用空格隔开。

四、解题思路

  1. 输入运动员的实力值;
  2. 定义获奖的集合trophyList,冠军组,亚军组,季军组;
  3. 定义运动员集合;
  4. 打比赛;
    • 定义胜利组;
    • 定义失败组;
    • 两两比赛;
      • 递增步数是2,因此如果是偶数,则全员都可以比较;
      • 如果是奇数,则最后一个运动员,因为没有比赛可以参加,直接晋级;
      • 比较当前运动员,奇数位运动员与下一个运动员
        • 实力大的进入胜利组,实力小的进入失败组;
        • 如果实力相等,id小的获胜
    • 将胜利组压到获奖的集合最前面,保证获胜的一直在前面;
  5. 如果冠军组不是一个人,那么在冠军组内继续打比赛,冠军赛吗?爽
  6. 输出最后的冠亚季军;

五、Java算法源码

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    // 运动员的实力值
    int[] strengthArr = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();

    // 获奖的集合trophyList,冠军组,亚军组,季军组
    LinkedList<ArrayList<Sportsman>> trophyList = new LinkedList<ArrayList<Sportsman>>();

    // 运动员集合
    ArrayList<Sportsman> sportsmanList = new ArrayList<Sportsman>();
    for (int i = 0; i < strengthArr.length; i++) {
        sportsmanList.add(new Sportsman(i, strengthArr[i]));
    }

    // 打比赛
    promotionCompetition(sportsmanList, trophyList);

    // 如果冠军组不是一个人,那么在冠军组内继续打比赛,冠军赛吗?爽
    while (trophyList.getFirst().size() > 1) {
        promotionCompetition(trophyList.removeFirst(), trophyList);
    }

    StringBuilder builder = new StringBuilder();
    builder.append(trophyList.get(0).get(0).id).append(" ").// 冠军
            append(trophyList.get(1).get(0).id).append(" ").// 亚军
            append(trophyList.get(2).get(0).id);// 季军
    System.out.println(builder);
}

/**
 * 打比赛
 *
 * @param sportsmanList 运动员集合
 * @param trophyList    获奖的集合
 */
public static void promotionCompetition(ArrayList<Sportsman> sportsmanList, LinkedList<ArrayList<Sportsman>> trophyList) {
    // 胜利组
    ArrayList<Sportsman> winList = new ArrayList<>();
    // 失败组
    ArrayList<Sportsman> failList = new ArrayList<>();

    // 两两比赛
    for (int i = 0; i < sportsmanList.size(); i += 2) {
        // 递增步数是2,因此如果是偶数,则全员都可以比较
        // 如果是奇数,则最后一个运动员,因为没有比赛可以参加,直接晋级
        if (i == sportsmanList.size() - 1) {
            winList.add(sportsmanList.get(sportsmanList.size() - 1));
            continue;
        }
        // 当前运动员,奇数位运动员
        Sportsman current = sportsmanList.get(i);
        // 下一个运动员
        Sportsman next = sportsmanList.get(i + 1);

        if (next.strength > current.strength) {
            winList.add(next);
            failList.add(current);
        } else if (next.strength < current.strength) {
            winList.add(current);
            failList.add(next);
        } else {
            // 实力值相等的情况,id小的情况下获胜
            winList.add(current);
            failList.add(next);
        }
    }

    // 保证获胜的一直在前面
    trophyList.addFirst(failList);
    trophyList.addFirst(winList);
}

// 运动员类
static class Sportsman {
    // 运动员的id
    int id;
    // 运动员的实力
    long strength;

    public Sportsman(int id, long strength) {
        this.id = id;
        this.strength = strength;
    }
}

六、效果展示

1、输入

99 98 92 97 96 96 95

2、输出

0 4 3

3、说明

华为OD机试真题 Java 实现【比赛的冠亚季军】【2023 B卷 100分】,附详细解题思路_第1张图片

华为OD机试真题 Java 实现【比赛的冠亚季军】【2023 B卷 100分】,附详细解题思路_第2张图片


下一篇:华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法

本文收录于,华为OD机试(JAVA)真题(A卷+B卷)

刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。

在这里插入图片描述

你可能感兴趣的:(搬砖工逆袭Java架构师,程序人生,学习,云原生,随机森林)