在线机考|2024华为实习&秋招&春招编程题(最新)——第1题_拔河比赛队员选拔_100分(八)

题目内容

某团队近期需要组织一支队伍参加拔河比赛,团队共有队员n人,比赛队员人数要求为m人,n>m,n个队员按编号,1到n的顺序参加k轮力量测试,每轮的测试成绩用正整数表示。

根据n个队员的力量测试成绩选择比赛队员m人,先选择k轮测试中最好成绩最大的队员,若有多人的最好成绩相等,则优先选择其中第二好成绩最大的队员,依次类推,最后若还有相等的情况,则优先选择编号较小的队员。每个人只能被选择一次。

输入描述

第1行,团队队员总数n,比赛队员要求的人数m,力量测试轮数k

第i+1行 (i从1到n),第i个队员参与力量测试第1~k轮的测试成绩,每轮成绩用空格分隔

n,m和k均为正整数,0<m<n<=10^3;0<k<=10^3,0<每轮测试成绩<=10^5

输出描述

按上述选择顺序选出的比赛队员编号的列表,用空格分隔

样例

输入:

4 3 3
10 12 14
11 12 13
12 15 10
12 11 13
输出:

3 1 2

解题思路

本题的关键在于对队员进行多维度的排序,以确保按照规定的优先级正确选出比赛队员。首先,对每位队员的k轮测试成绩进行降序排序,确保每个队员的成绩从高到低排列。然后,按照每位队员排序后的成绩列表逐项进行比较,优先选择在各个成绩项上表现更优的队员。如果在所有成绩项上都相同,则优先选择编号较小的队员。通过这种多关键字排序的方法,可以有效地从n名队员中筛选出符合要求的m名比赛队员,保证选择过程符合题目要求的优先级规则。

  1. 数据预处理:对于每个队员,将其k轮测试成绩排序,降序排列。这样每个队员的成绩列表从最好到最差。
  2. 排序比较:按照以下优先级对所有队员进行排序:
  • 首先比较每个队员的第一个成绩(最好成绩),成绩高者优先。
  • 若第一成绩相同,则比较第二个成绩,成绩高者优先。
  • 依此类推,直到所有k个成绩都比较完。
  • 若所有成绩都相同,则编号小的队员优先。
  1. 选择队员:排序完成后,选择前m个队员的编号作为比赛队员。

编程实现

C++

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

// 定义队员结构体
struct Player {
    int id; // 队员编号
    vector<int> scores; // 排序后的成绩列表
};

// 自定义比较函数
bool comparePlayers(const Player &a, const Player &b) {
    // 比较每个成绩
    for(int i = 0; i < a.scores.size(); ++i){
        if(a.scores[i] != b.scores[i]){
            return a.scores[i] > b.scores[i]; // 成绩高者优先
        }
    }
    // 成绩完全相同,比较编号
    return a.id < b.id;
}

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n, m, k;
    cin >> n >> m >> k; // 输入n, m, k
    vector<Player> players(n);
    for(int i = 0; i < n; ++i){
        players[i].id = i + 1; // 编号从1开始
        players[i].scores.resize(k);
        for(int j = 0; j < k; ++j){
            cin >> players[i].scores[j]; // 输入每轮成绩
        }
        // 将成绩排序降序
        sort(players[i].scores.begin(), players[i].scores.end(), greater<int>());
    }
    // 对所有队员排序
    sort(players.begin(), players.end(), comparePlayers);
    // 输出前m个队员的编号
    for(int i = 0; i < m; ++i){
        if(i > 0) cout << ' ';
        cout << players[i].id;
    }
    return 0;
}

Python

# 定义队员类
class Player:
    def __init__(self, id, scores):
        self.id = id
        # 排序成绩降序
        self.scores = sorted(scores, reverse=True)
    
    # 定义比较函数
    def __lt__(self, other):
        for a, b in zip(self.scores, other.scores):
            if a != b:
                return a > b
        return self.id < other.id

def main():
    import sys
    input = sys.stdin.read
    data = input().split()
    idx = 0
    n, m, k = map(int, data[idx:idx+3])
    idx +=3
    players = []
    for i in range(1, n+1):
        scores = list(map(int, data[idx:idx+k]))
        idx +=k
        player = Player(i, scores)
        players.append(player)
    # 排序
    players.sort()
    # 输出前m个队员的编号
    selected = [str(player.id) for player in players[:m]]
    print(' '.join(selected))

if __name__ == "__main__":
    main()

Java

import java.util.*;
import java.io.*;

public class Main {
    // 定义队员类
    static class Player implements Comparable<Player>{
        int id;
        List<Integer> scores;
        
        Player(int id, List<Integer> scores){
            this.id = id;
            // 排序降序
            Collections.sort(this.scores = scores, Collections.reverseOrder());
        }
        
        @Override
        public int compareTo(Player other){
            for(int i = 0; i < this.scores.size(); i++){
                if(!this.scores.get(i).equals(other.scores.get(i))){
                    return other.scores.get(i) - this.scores.get(i); // 降序
                }
            }
            return this.id - other.id; // 编号升序
        }
    }
    
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] first = br.readLine().trim().split("\\s+");
        int n = Integer.parseInt(first[0]);
        int m = Integer.parseInt(first[1]);
        int k = Integer.parseInt(first[2]);
        List<Player> players = new ArrayList<>();
        for(int i=1; i<=n; i++){
            String[] line = br.readLine().trim().split("\\s+");
            List<Integer> scores = new ArrayList<>();
            for(int j=0; j<k; j++) scores.add(Integer.parseInt(line[j]));
            players.add(new Player(i, scores));
        }
        // 排序
        Collections.sort(players);
        // 输出前m个队员的编号
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<m; i++){
            if(i >0) sb.append(' ');
            sb.append(players.get(i).id);
        }
        System.out.println(sb.toString());
    }
}