华为OD机试 - 统计射击比赛成绩 - 逻辑分析(Python/JS/C/C++ 2025 A卷 100分)

在这里插入图片描述

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

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

一、题目描述

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

条件如下:

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

二、输入描述

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

三、输出描述

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

四、测试用例

测试用例1:

1、输入

6
1,2,1,2,1,2
10,20,30,40,50,60

2、输出

2,1

3、说明

选手1的分数:10,30,50 → 和为90
选手2的分数:20,40,60 → 和为120
排序后为2(120),1(90)

测试用例2:

1、输入

5
10,20,10,20,10
100,90,80,70,60

2、输出

10

3、说明

选手10的分数:100,80,60 → 和为240
选手20的分数:90,70 → 少于3个分数,忽略
仅选手10有至少3次射击,但由于只有一个选手,输出为10。

五、解题思路

  1. 第一行输入选手人数;
  2. 第二行输入选手ID;
  3. 第三行输入选手所得分数;
  4. 定义listMap,key:选手ID,value:每个选手的分数列表;
  5. 定义map,key:选手ID,value:每个选手最高的3个分数之和;
    • 如果一个选手成绩少于3个,则认为选手的所有成绩无效,排名忽略该选手;
    • 对每个选手的分数进行降序排序;
    • 计算每个选手最高的3个分数之和;
  6. 按照每个选手最高的3个分数之和降序排序,如果分数相等,按选手ID序列降序排序,否则先按分数降序排序;
  7. 输出降序排名后的选手ID序列。

六、Python算法源码

# 导入所需的模块
from collections import defaultdict
import heapq

def main():
    # 读取射击次数N
    n = int(input().strip())
    # 读取选手ID列表
    player_arr = list(map(int, input().strip().split(',')))
    # 读取分数列表
    score_arr = list(map(int, input().strip().split(',')))

    # 使用字典存储选手ID对应的最小堆(维护前3高分)
    player_scores = defaultdict(list)

    for i in range(n):
        player = player_arr[i]
        score = score_arr[i]
        heapq.heappush(player_scores[player], score)
        if len(player_scores[player]) > 3:
            heapq.heappop(player_scores[player])  # 移除最小的分数,保持前3高分

    # 创建一个字典存储选手ID与分数和(仅包含至少3次射击的选手)
    valid_players = {}
    for player, scores in player_scores.items():
        if len(scores) == 3:
            valid_players[player] = sum(scores)

    # 对选手进行排序:首先按分数和降序,其次按选手ID降序
    sorted_players = sorted(valid_players.items(), key=lambda x: (-x[1], -x[0]))

    # 构建输出结果
    result = ','.join(str(player) for player, _ in sorted_players)
    print(result)

if __name__ == "__main__":
    main()

七、JavaScript算法源码

// 导入所需模块
const readline = require('readline');

function main() {
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });

    let input = [];
    rl.on('line', function(line) {
        input.push(line.trim());
        if (input.length === 3) {
            rl.close();
        }
    }).on('close', function() {
        // 读取射击次数N
        const n = parseInt(input[0]);
        // 读取选手ID数组
        const playerArr = input[1].split(',').map(Number);
        // 读取分数数组
        const scoreArr = input[2].split(',').map(Number);

        // 使用Map存储选手ID对应的分数数组
        const playerScores = new Map();

        for (let i = 0; i < n; i++) {
            const player = playerArr[i];
            const score = scoreArr[i];
            if (!playerScores.has(player)) {
                playerScores.set(player, []);
            }
            const scores = playerScores.get(player);
            scores.push(score);
            // 保持分数数组为前3高分
            scores.sort((a, b) => b - a);
            if (scores.length > 3) {
                scores.pop();
            }
            playerScores.set(player, scores);
        }

        // 创建一个数组存储有效选手及其分数和
        const validPlayers = [];
        for (let [player, scores] of playerScores.entries()) {
            if (scores.length === 3) {
                const sum = scores.reduce((a, b) => a + b, 0);
                validPlayers.push([player, sum]);
            }
        }

        // 对选手进行排序:首先按分数和降序,其次按选手ID降序
        validPlayers.sort((a, b) => {
            if (b[1] !== a[1]) {
                return b[1] - a[1];
            } else {
                return b[0] - a[0];
            }
        });

        // 构建输出结果
        const result = validPlayers.map(item => item[0]).join(',');
        console.log(result);
    });
}

main();

八、C算法源码

#include <stdio.h>
#include <stdlib.h>

// 定义选手结构体
typedef struct {
    int id;
    int scores[100];
    int count;
} Player;

// 比较函数,用于qsort,降序排序
int compare_desc(const void* a, const void* b) {
    return (*(int*)b - *(int*)a);
}

// 比较函数,用于最终排序
int final_compare(const void* a, const void* b) {
    // 结构体指针
    Player p1 = *(Player*)a;
    Player p2 = *(Player*)b;
    // 计算分数和
    int sum1 = 0, sum2 = 0;
    for(int i=0;i<3;i++) sum1 += p1.scores[i];
    for(int i=0;i<3;i++) sum2 += p2.scores[i];
    if(sum2 != sum1) return sum2 - sum1; // 分数和降序
    else return p2.id - p1.id; // ID降序
}

int main(){
    int n;
    scanf("%d\n", &n);
    int playerArr[n];
    int scoreArr[n];
    // 读取选手ID
    for(int i=0;i<n;i++){
        scanf("%d", &playerArr[i]);
        if(i < n-1){
            char c;
            scanf("%c", &c); // 读取逗号
        }
    }
    // 读取分数
    for(int i=0;i<n;i++){
        scanf("%d", &scoreArr[i]);
        if(i < n-1){
            char c;
            scanf("%c", &c); // 读取逗号
        }
    }

    // 创建选手数组
    Player players[100];
    int player_count = 0;
    for(int i=0;i<n;i++){
        int id = playerArr[i];
        int score = scoreArr[i];
        // 查找选手是否已存在
        int found = 0;
        for(int j=0;j<player_count;j++){
            if(players[j].id == id){
                players[j].scores[players[j].count++] = score;
                found = 1;
                break;
            }
        }
        // 如果不存在,新增选手
        if(!found){
            players[player_count].id = id;
            players[player_count].scores[0] = score;
            players[player_count].count = 1;
            player_count++;
        }
    }

    // 筛选有效选手,并计算前3高分和
    Player validPlayers[100];
    int valid_count = 0;
    for(int i=0;i<player_count;i++){
        if(players[i].count >=3 ){
            // 对分数进行降序排序
            qsort(players[i].scores, players[i].count, sizeof(int), compare_desc);
            // 取前3个分数
            for(int j=0;j<3;j++) {
                validPlayers[valid_count].scores[j] = players[i].scores[j];
            }
            validPlayers[valid_count].id = players[i].id;
            valid_count++;
        }
    }

    // 对有效选手进行排序
    qsort(validPlayers, valid_count, sizeof(Player), final_compare);

    // 输出结果
    for(int i=0;i<valid_count;i++){
        printf("%d", validPlayers[i].id);
        if(i != valid_count -1) printf(",");
    }
    printf("\n");
    return 0;
}

九、C++算法源码

#include <bits/stdc++.h>
using namespace std;

// 定义选手结构体
struct Player {
    int id;
    vector<int> scores;
};

// 比较函数,用于排序
bool comparePlayers(const Player &a, const Player &b) {
    // 计算分数和
    int sumA = 0, sumB = 0;
    for(int i=0;i<3;i++) sumA += a.scores[i];
    for(int i=0;i<3;i++) sumB += b.scores[i];
    if(sumA != sumB) return sumA > sumB; // 分数和降序
    else return a.id > b.id; // ID降序
}

int main(){
    int n;
    cin >> n;
    // 读取选手ID
    vector<int> playerArr(n);
    char c;
    for(int i=0;i<n;i++){
        cin >> playerArr[i];
        if(i < n-1) cin >> c; // 读取逗号
    }
    // 读取分数
    vector<int> scoreArr(n);
    for(int i=0;i<n;i++){
        cin >> scoreArr[i];
        if(i < n-1) cin >> c; // 读取逗号
    }

    // 使用map存储选手ID对应的分数
    map<int, vector<int>> playerScores;
    for(int i=0;i<n;i++){
        int player = playerArr[i];
        int score = scoreArr[i];
        playerScores[player].push_back(score);
    }

    // 创建有效选手列表
    vector<Player> validPlayers;
    for(auto &entry : playerScores){
        if(entry.second.size() >=3 ){
            // 对分数进行降序排序
            sort(entry.second.begin(), entry.second.end(), greater<int>());
            Player p;
            p.id = entry.first;
            // 取前3个分数
            p.scores.assign(entry.second.begin(), entry.second.begin()+3);
            validPlayers.push_back(p);
        }
    }

    // 对有效选手进行排序
    sort(validPlayers.begin(), validPlayers.end(), comparePlayers);

    // 构建输出
    string result = "";
    for(int i=0;i<validPlayers.size();i++){
        result += to_string(validPlayers[i].id);
        if(i != validPlayers.size()-1) result += ",";
    }
    cout << result << endl;
    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 A卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

哪 吒

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

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

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

打赏作者

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

抵扣说明:

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

余额充值