题目内容
某团队近期需要组织一支队伍参加拔河比赛,团队共有队员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名比赛队员,保证选择过程符合题目要求的优先级规则。
- 数据预处理:对于每个队员,将其k轮测试成绩排序,降序排列。这样每个队员的成绩列表从最好到最差。
- 排序比较:按照以下优先级对所有队员进行排序:
- 首先比较每个队员的第一个成绩(最好成绩),成绩高者优先。
- 若第一成绩相同,则比较第二个成绩,成绩高者优先。
- 依此类推,直到所有k个成绩都比较完。
- 若所有成绩都相同,则编号小的队员优先。
- 选择队员:排序完成后,选择前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, kvector<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 > breturn self.id < other.iddef main():import sysinput = sys.stdin.readdata = input().split()idx = 0n, m, k = map(int, data[idx:idx+3])idx +=3players = []for i in range(1, n+1):scores = list(map(int, data[idx:idx+k]))idx +=kplayer = 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());}@Overridepublic 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());}
}