【2024华为OD-E卷-100分-比赛】(题目+思路+Java&C++&Python解析)

题目

题目描述

在一个编程比赛中,有 n 名选手参赛。每个选手都有一个唯一的编号,从 1 到 n。比赛结束后,得到了一个包含每个选手得分的数组 scores,其中 scores[i] 表示编号为 i+1 的选手的得分。

现在需要计算每个选手的排名。排名的规则如下:

  1. 得分越高的选手排名越靠前。
  2. 如果两个选手得分相同,则编号较小的选手排名靠前。

根据这个规则,返回一个包含每个选手排名的数组 ranks,其中 ranks[i] 表示编号为 i+1 的选手的排名。

输入

  • n:整数,表示参赛选手的数量(1 <= n <= 10^5)。
  • scores:长度为 n 的整数数组,表示每个选手的得分(-10^9 <= scores[i] <= 10^9)。

输出

  • ranks:长度为 n 的整数数组,表示每个选手的排名。

示例

  • 输入:n = 5,scores = [10, 20, 20, 10, 30]
  • 输出:[4, 2, 3, 5, 1]

思路

  1. 存储选手信息: 使用一个类或者结构体来存储选手的编号和得分,这样可以方便后续排序。
  2. 排序: 根据题目要求的排名规则,对选手进行排序。首先按得分降序排序,如果得分相同,则按编号升序排序。
  3. 计算排名: 排序后,遍历排序后的选手列表,为每个选手分配排名。
  4. 输出结果: 将计算好的排名按原始编号顺序输出。

Java编码解析

import java.util.*;

public class Main {
    static class Player {
        int id;
        int score;

        Player(int id, int score) {
            this.id = id;
            this.score = score;
        }
    }

    public static int[] getRanks(int n, int[] scores) {
        List<Player> players = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            players.add(new Player(i + 1, scores[i]));
        }

        Collections.sort(players, (p1, p2) -> {
            if (p1.score != p2.score) {
                return Integer.compare(p2.score, p1.score); // 降序排序得分
            } else {
                return Integer.compare(p1.id, p2.id); // 升序排序编号
            }
        });

        int[] ranks = new int[n];
        for (int i = 0; i < n; i++) {
            ranks[players.get(i).id - 1] = i + 1; // 根据原始编号设置排名
        }

        return ranks;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] scores = new int[n];
        for (int i = 0; i < n; i++) {
            scores[i] = scanner.nextInt();
        }
        int[] ranks = getRanks(n, scores);
        for (int rank : ranks) {
            System.out.print(rank + " ");
        }
    }
}

C++编码解析

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

struct Player {
    int id;
    int score;
};

bool compare(const Player& p1, const Player& p2) {
    if (p1.score != p2.score) {
        return p1.score > p2.score; // 降序排序得分
    } else {
        return p1.id < p2.id; // 升序排序编号
    }
}

vector<int> getRanks(int n, const vector<int>& scores) {
    vector<Player> players(n);
    for (int i = 0; i < n; i++) {
        players[i] = {i + 1, scores[i]};
    }

    sort(players.begin(), players.end(), compare);

    vector<int> ranks(n);
    for (int i = 0; i < n; i++) {
        ranks[players[i].id - 1] = i + 1; // 根据原始编号设置排名
    }

    return ranks;
}

int main() {
    int n;
    cin >> n;
    vector<int> scores(n);
    for (int i = 0; i < n; i++) {
        cin >> scores[i];
    }
    vector<int> ranks = getRanks(n, scores);
    for (int rank : ranks) {
        cout << rank << " ";
    }
    return 0;
}

Python编码解析

def get_ranks(n, scores):
    players = [(i + 1, scores[i]) for i in range(n)]
    players.sort(key=lambda x: (-x[1], x[0]))  # 按得分降序,编号升序排序

    ranks = [0] * n
    for i in range(n):
        ranks[players[i][0] - 1] = i + 1  # 根据原始编号设置排名

    return ranks

if __name__ == "__main__":
    n = int(input().strip())
    scores = list(map(int, input().strip().split()))
    ranks = get_ranks(n, scores)
    print(" ".join(map(str, ranks)))

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

执着的小火车

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值