#P3033. 智能成绩表(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 196
            Accepted: 55
            Difficulty: 4
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>排序算法          
 
智能成绩表(100分)
思路:自定义排序
可以定义一个结构体数组,里面存储学生的姓名和每一个科目的分数,然后根据题目给定的排序规则,自定义排序即可。
注意:如果科目不存在,需要按照总分进行排序。
JavaScript代码
const readline = require('readline');
const r1 = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});
let input = [];
let students = [];
let keyIndex = 0;
r1.on('line', function(line) {
  input.push(line.trim());
}).on('close', function() {
  let [n, m] = input[0].split(' ').map(Number);
  let courseNames = input[1].split(' ');
  for (let i = 1; i <= n; i++) {
    let studentInfo = input[i + 1].split(' ');
    let student = {
      name: studentInfo[0],
      scores: studentInfo.slice(1).map(Number)
    };
    student.scores.push(student.scores.reduce((a, b) => a + b, 0));
    students.push(student);
  }
  let key = input[n + 2];
  keyIndex = courseNames.indexOf(key);
  if (keyIndex === -1) keyIndex = m;
  students.sort((a, b) => {
    if (a.scores[keyIndex] !== b.scores[keyIndex]) {
      return b.scores[keyIndex] - a.scores[keyIndex];
    }
    return a.name.localeCompare(b.name);
  });
  console.log(students.map(student => student.name).join(' '));
});
Java代码
import java.util.*;
class Main {
    // 存储学生信息和成绩的结构体
    static class Student {
        String name; // 学生名字
        List<Integer> scores; // 每门课成绩
    }
    static Student[] students = new Student[10004]; // 存储学生信息的数组
    static int keyIndex; // 要排序的课程名的下标
    // 自定义排序函数
    static Comparator<Student> studentComparator = new Comparator<Student>() {
        @Override
        public int compare(Student a, Student b) {
            if (!a.scores.get(keyIndex).equals(b.scores.get(keyIndex))) {
                return b.scores.get(keyIndex) - a.scores.get(keyIndex);
            }
            return a.name.compareTo(b.name);
        }
    };
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String[] courseNames = new String[1000]; // 课程名数组
        int n, m; // 学生数量和课程数量
        n = sc.nextInt();
        m = sc.nextInt();
        for (int i = 0; i < m; i++) {
            courseNames[i] = sc.next(); // 读入课程名字
        }
        for (int i = 1; i <= n; i++) {
            students[i] = new Student();
            students[i].name = sc.next(); // 读取学生名字
            int sum = 0;
            students[i].scores = new ArrayList<>();
            for (int j = 0; j < m; j++) {
                int score = sc.nextInt();
                students[i].scores.add(score); // 读取每门课成绩
                sum += score;
            }
            students[i].scores.add(sum); // 将总分放入成绩数组末尾
        }
        String key = sc.next(); // 要排序的课程名
        keyIndex = m; // 若没找到,赋值为最后一个位置,也就是总分
        for (int i = 0; i < m; i++) { // 寻找这个课程名的下标
            if (courseNames[i].equals(key)) {
                keyIndex = i;
                break;
            }
        }
        Arrays.sort(students, 1, n + 1, studentComparator); // 排序
        for (int i = 1; i <= n; i++) {
            System.out.print(students[i].name);
            if (i == n) System.out.println();
            else System.out.print(" ");
        }
    }
}
Python代码
class Student:
    def __init__(self):
        self.name = ""  # 学生名字
        self.scores = []  # 每门课成绩
students = [Student() for _ in range(10004)]  # 存储学生信息的数组
key_index = 0  # 要排序的课程名的下标
n, m = map(int, input().split())  # 学生数量和课程数量
course_names = input().split()  # 课程名数组
for i in range(1, n + 1):
    student_info = input().split()
    students[i].name = student_info[0]  # 读取学生名字
    total_score = 0
    students[i].scores = list(map(int, student_info[1:]))  # 读取每门课成绩
    total_score = sum(students[i].scores)  # 计算总分
    students[i].scores.append(total_score)  # 将总分放入成绩数组末尾
key = input()  # 要排序的课程名
key_index = m  # 若没找到,赋值为最后一个位置,也就是总分
for i in range(m):  # 寻找这个课程名的下标
    if course_names[i] == key:
        key_index = i
        break
students = students[1:n+1]  # 仅保留有效学生信息
students.sort(key=lambda x: (-x.scores[key_index], x.name))  # 排序
for i in range(n):
    if i != n - 1:
        print(students[i].name, end=" ")
    else:
        print(students[i].name)
C++代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 存储学生信息和成绩的结构体
struct Student {
    string name; // 学生名字
    vector<int> scores; // 每门课成绩
};
Student students[10004]; // 存储学生信息的数组
int keyIndex; // 要排序的课程名的下标
// 自定义排序函数
bool compare(Student &a, Student &b) {
    if (a.scores[keyIndex] != b.scores[keyIndex]) // 如果分数不同,则先比较分数
        return a.scores[keyIndex] > b.scores[keyIndex];
    return a.name < b.name; // 反之比较学生名字
}
int main() {
    string courseNames[1000]; // 课程名数组
    int n, m; // 学生数量和课程数量
    cin >> n >> m; // 读取学生数量和课程数量
    for (int i = 0; i < m; i++) {
        cin >> courseNames[i]; // 读入课程名字
    }
    for (int i = 1; i <= n; i++) {
        cin >> students[i].name; // 读取学生名字
        int sum = 0;
        for (int j = 0; j < m; j++) {
            int score;
            cin >> score;
            students[i].scores.push_back(score); // 读取每门课成绩
            sum += score;
        }
        students[i].scores.push_back(sum); // 将总分放入成绩数组末尾
    }
    string key; // 要排序的课程名
    cin >> key;
    keyIndex = m; // 若没找到,赋值为最后一个位置,也就是总分
    for (int i = 0; i < m; i++) { // 寻找这个课程名的下标
        if (courseNames[i] == key) {
            keyIndex = i;
            break;
        }
    }
    sort(students + 1, students + 1 + n, compare); // 排序
    for (int i = 1; i <= n; i++) {
        cout << students[i].name;
        if (i == n) cout << endl;
        else cout << " ";
    }
    return 0;
}
        题目描述
小明来到学校当老师,需要将学生按考试总分或单科分数进行排名,你能帮帮他吗?
输入描述
第 1 行输入两个整数,学生人数 n 和科目数量 m。(0<n<100,0<m<10)
第 2 行输入 m 个科目名称,彼此之间用空格隔开。科目名称只由英文字母构成,单个长度不超过 10 个字符,科目的出现顺序和后续输入的学生成绩一一对应,不会出现重复的科目名称。
第 3 行开始的 n 行,每行包含一个学生的姓名和该生 m 个科目的成绩(空格隔开),学生不会重名。学生的姓名只由英文字母构成,长度不超过 10 个字符。成绩是 0 ~ 100的整数,依次对应第 2 行输入的科目
第 n+2 行,输入用作排名的科目名称,若科目不存在,则按总分进行排序。
输出描述
输出一行,按成绩排序后的学生名字,空格隔开,成绩相同的按照学生的姓名字典顺序进行排序。
样例1
输入
3 2
yuwen shuxue
fangfang 95 90
xiaohua 88 98
minmin 100 82
shuxue
输出
xiaohua fangfang minmin
说明:按照shuxue成绩排名依次是 xiaohua fangfang minmin
样例2
输入
3 2
yuwen shuxue
fangfang 95 90
xiaohua 88 95
minmin 90 95
zongfen
输出
fangfang minmin xiaohua
说明:排序科目不存在,按总分排序 , fangfang 和 minmin 总分相同,按姓名的字典序顺序,fangfang 排在前面