华为OD机试 2025A卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
给定一个射击比赛成绩单,包含多个选手若干次射击的成绩分数,请对每个选手按其最高3个分数之和进行降序排名,输出降序排名后的选手ID序列。
条件如下:
- 一个选手可以有多个射击成绩的分数,且次序不固定
- 如果一个选手成绩少于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。
五、解题思路
- 第一行输入选手人数;
- 第二行输入选手ID;
- 第三行输入选手所得分数;
- 定义listMap,key:选手ID,value:每个选手的分数列表;
- 定义map,key:选手ID,value:每个选手最高的3个分数之和;
- 如果一个选手成绩少于3个,则认为选手的所有成绩无效,排名忽略该选手;
- 对每个选手的分数进行降序排序;
- 计算每个选手最高的3个分数之和;
- 按照每个选手最高的3个分数之和降序排序,如果分数相等,按选手ID序列降序排序,否则先按分数降序排序;
- 输出降序排名后的选手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算法的适用场景,发现新题目,随时更新。