题目描述
小明来到某学校当老师,需要将学生按考试总分或单科分数进行排名,你能帮帮他吗?
输入描述
第 1 行输入两个整数,学生人数 n 和科目数量 m。
- 0 < n < 100
- 0 < m < 10
第 2 行输入 m 个科目名称,彼此之间用空格隔开。
- 科目名称只由英文字母构成,单个长度不超过10个字符。
- 科目的出现顺序和后续输入的学生成绩一一对应。
- 不会出现重复的科目名称。
第 3 行开始的 n 行,每行包含一个学生的姓名和该生 m 个科目的成绩(空格隔开)
- 学生不会重名。
- 学生姓名只由英文字母构成,长度不超过10个字符。
- 成绩是0~100的整数,依次对应第2行种输入的科目。
第n+2行,输入用作排名的科目名称。若科目不存在,则按总分进行排序。
输出描述
输出一行,按成绩排序后的学生名字,空格隔开。成绩相同的按照学生姓名字典顺序排序。
用例
输入 | 3 2 yuwen shuxue fangfang 95 90 xiaohua 88 95 minmin 100 82 shuxue |
输出 | xiaohua fangfang minmin |
说明 | 按shuxue成绩排名,依次是xiaohua、fangfang、minmin |
输入 | 3 2 yuwen shuxue fangfang 95 90 xiaohua 88 95 minmin 90 95 zongfen |
输出 | fangfang minmin xiaohua |
说明 | 排序科目不存在,按总分排序,fangfang和minmin总分相同,按姓名的字典顺序,fangfang排在前面 |
题目解析
本题是一道排序题。难度在于排序规则是动态的,不是固定的。
本题要求按照最后一行输入的科目的分数进行排序,如果对应科目不存在,则按照总分进行排序。
我的解题思路是:
首先,定义一个排名要素数组rank,分别记录各科成绩以及总分,即该排名要素数组rank的长度为 m + 1。
- 第rank[0]~rank[m-1]上,记录的是第二行输入科目顺序对应科目分数。
- 第rank[m]上,记录的是所有科目的总分。
然后,定义一个有效要素索引(即最终用于指定规则的排序要素的索引),比如:
- 最后一行输入了shuxue,那么我就去第二行输入:yuwen shuxue,中去找对应出现序号为 1,那么有效要素的索引就是1,最终用于制定排序规则的值就是 rank[1]。
- 如果最后一行输入的科目,在第二行中不存在,那么就是按照总分制定排序规则,此时排序要素取 rank[m]。
如果排序要素值相同(可能是某科成绩,可能是总分),那么就再按照学生姓名的字典序排序。
更多实现细节请看代码,已添加详细注释。
JavaScript算法源码
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
class Student {
constructor(name, rank) {
this.name = name; // 学生姓名
this.rank = rank; // 排名要素
}
}
// 学生人数, 科目数量
const [n, m] = (await readline()).split(" ").map(Number);
// key是科目名称,val是科目出现顺序的序号
const subject_rankIdx = {};
// 输入的m个科目
const subjects = (await readline()).split(" ");
for (let i = 0; i < m; i++) {
subject_rankIdx[subjects[i]] = i;
}
const students = [];
for (let i = 0; i < n; i++) {
const tmp = (await readline()).split(" ");
// 学生姓名
const name = tmp[0];
// 学生给定科目的分数(m个)
const scores = tmp.slice(1).map(Number);
// 学生所有科目的总分
const score_sum = scores.reduce((a, b) => a + b);
// 排名要素,0~m-1索引上的是给定科目成绩,m索引上的是总分
const rank = [...scores, score_sum];
students.push(new Student(name, rank));
}
// 用作排名的科目名称
const subject = await readline();
// 用作排名的科目名称的排名要素序号
let rankIdx = subject_rankIdx[subject];
// 如果用作排名的科目名称不存在,则按总分排名,对应序号是m
if (rankIdx == undefined) {
rankIdx = m;
}
// 按照排名要素排名,如果排名要素值相同,则按照学生姓名字典序排序
students.sort((a, b) =>
a.rank[rankIdx] != b.rank[rankIdx]
? b.rank[rankIdx] - a.rank[rankIdx]
: strcmp(a.name, b.name)
);
console.log(students.map((a) => a.name).join(" "));
})();
function strcmp(a, b) {
if (a == b) {
return 0;
} else if (a > b) {
return 1;
} else {
return -1;
}
}
Java算法源码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import java.util.StringJoiner;
public class Main {
static class Student {
String name; // 学生姓名
int[] rank; // 排名要素
public Student(String name, int[] rank) {
this.name = name;
this.rank = rank;
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 学生人数
int n = sc.nextInt();
// 科目数量
int m = sc.nextInt();
// key是科目名称,val是科目出现顺序的序号
HashMap<String, Integer> subject_rankIdx = new HashMap<>();
for (int i = 0; i < m; i++) {
subject_rankIdx.put(sc.next(), i);
}
ArrayList<Student> students = new ArrayList<>();
for (int i = 0; i < n; i++) {
// 学生姓名
String name = sc.next();
// rank记录学生排名的要素(0~m-1索引上记录的是各科成绩,m索引上记录的是总分)
int[] rank = new int[m + 1];
// 学生的总分
int score_sum = 0;
// m 个科目成绩
for (int j = 0; j < m; j++) {
rank[j] = sc.nextInt();
score_sum += rank[j];
}
rank[m] = score_sum;
students.add(new Student(name, rank));
}
// 输入用作排名的科目名称
// 根据用作排名的科目名称获取对应排名要素序号,如果不存在,则按总分排序,排名要素序号取m
int rankIdx = subject_rankIdx.getOrDefault(sc.next(), m);
students.sort(
(a, b) ->
a.rank[rankIdx] != b.rank[rankIdx]
? b.rank[rankIdx] - a.rank[rankIdx]
: a.name.compareTo(b.name));
StringJoiner sj = new StringJoiner(" ");
for (Student student : students) {
sj.add(student.name);
}
System.out.println(sj);
}
}
Python算法源码
class Student:
def __init__(self, name, rank):
self.name = name
self.rank = rank
# 学生人数, 科目数量
n, m = map(int, input().split())
# key是科目名称,val是科目出现顺序的序号
subject_rankIdx = {}
# 输入的m个科目
subjects = input().split()
for i in range(m):
subject_rankIdx[subjects[i]] = i
students = []
for i in range(n):
tmp = input().split()
# 学生姓名
name = tmp[0]
# 学生给定科目的分数(m个)
scores = list(map(int, tmp[1:]))
# 排名要素,0~m-1索引上的是给定科目成绩,m索引上的是总分
rank = []
rank.extend(scores)
rank.append(sum(scores))
students.append(Student(name, rank))
# 用作排名的科目名称
subject = input()
# 用作排名的科目名称的排名要素序号, 如果用作排名的科目名称不存在,则按总分排名,对应序号是m
rankIdx = subject_rankIdx.get(subject, m)
# 按照排名要素排名,如果排名要素值相同,则按照学生姓名字典序排序
students.sort(key=lambda x: (-x.rank[rankIdx], x.name))
print(" ".join(map(lambda x: x.name, students)))
C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_N 100
#define MAX_M 10
#define MAX_SUBJECT_LEN 11
#define MAX_STU_NAME_LEN 11
typedef struct {
char name[MAX_STU_NAME_LEN]; // 学生姓名
int *rank; // 排名要素
} Student;
Student *new_Student(char *name, int *rank) {
Student *student = (Student *) malloc(sizeof(Student));
strcpy(student->name, name);
student->rank = rank;
return student;
}
int rankIdx;
int cmp(const void* a, const void* b) {
Student* A = *((Student**) a);
Student* B = *((Student**) b);
if(A->rank[rankIdx] != B->rank[rankIdx]) {
return B->rank[rankIdx] - A->rank[rankIdx];
} else {
return strcmp(A->name, B->name);
}
}
int main() {
// 学生人数, 科目数量
int n, m;
scanf("%d %d", &n, &m);
// 记录科目出现顺序
char subjects[MAX_M][MAX_SUBJECT_LEN];
for (int i = 0; i < m; i++) {
scanf("%s", subjects[i]);
}
Student *students[MAX_N] = {NULL};
int students_size = 0;
for (int i = 0; i < n; i++) {
// 学生姓名
char name[MAX_STU_NAME_LEN];
scanf("%s", name);
// rank记录学生排名的要素(0~m-1索引上记录的是各科成绩,m索引上记录的是总分)
int *rank = (int *) calloc(m + 1, sizeof(int));
// 学生的总分
int score_sum = 0;
// m 个科目成绩
for (int j = 0; j < m; j++) {
scanf("%d", &rank[j]);
score_sum += rank[j];
}
rank[m] = score_sum;
students[students_size++] = new_Student(name, rank);
}
char subject[MAX_STU_NAME_LEN];
scanf("%s", subject);
// 输入用作排名的科目名称
// 根据用作排名的科目名称获取对应排名要素序号,如果不存在,则按总分排序,排名要素序号取m
rankIdx = m;
for (int i = 0; i < m; i++) {
if (strcmp(subject, subjects[i]) == 0) {
rankIdx = i;
break;
}
}
qsort(students, students_size, sizeof(Student*), cmp);
printf("%s", students[0]->name);
for(int i=1; i<students_size; i++) {
printf(" %s",students[i]->name);
}
return 0;
}
免责声明:
1、IT资源小站为非营利性网站,全站所有资料仅供网友个人学习使用,禁止商用
2、本站所有文档、视频、书籍等资料均由网友分享,本站只负责收集不承担任何技术及版权问题
3、如本帖侵犯到任何版权问题,请立即告知本站,本站将及时予与删除下载链接并致以最深的歉意
4、本帖部分内容转载自其它媒体,但并不代表本站赞同其观点和对其真实性负责
5、一经注册为本站会员,一律视为同意网站规定,本站管理员及版主有权禁止违规用户
6、其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和IT资源小站的同意
7、IT资源小站管理员和版主有权不事先通知发贴者而删除本文
评论0