返回目录
题目描述
小明来到某学校当老师,需要将学生按考试总分或单科分数进行排名,你能帮帮他吗?
输入描述
第 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]。
如果排序要素值相同(可能是某科成绩,可能是总分),那么就再按照学生姓名的字典排序。
更多实现细节请看代码,已添加详细注释。
Python算法源码
# 定义学生类
class Student:
def __init__(self, name):
self.name = name
self.rank = []
# 比较函数,用于排序学生
def compare(s1, s2):
return s2.name < s1.name # 按姓名降序排列
if __name__ == "__main__":
n, m = map(int, input().split()) # 输入学生数和科目数
# 输入科目名称并创建科目索引映射
subjects = [input() for _ in range(m)]
# 输入学生数据
students = []
for _ in range(n):
name = input() # 输入学生姓名
ranks = list(map(int, input().split())) # 输入学生各科目排名
total_score = sum(ranks) # 计算总分
ranks.append(total_score) # 将总分存入排名数组的最后一个元素
student = Student(name)
student.rank = ranks
students.append(student)
subject = input() # 输入用于排名的科目
rank_idx = m # 默认为总分排名
for i in range(m):
if subject == subjects[i]:
rank_idx = i
break
# 根据排名排序学生
students.sort(key=lambda x: x.name, reverse=True)
# 打印排序后的学生姓名
for student in students:
print(student.name, end=" ")
# 释放动态分配的内存(Python不需要手动释放内存)
C算法源码
以下是对程序中各部分的中文注释:
include <stdio.h>
include <stdlib.h>
include <string.h>
// 定义学生结构体
typedef struct {
char name[100]; // 学生姓名
int *rank; // 学生排名数组
} Student;
// 比较函数,用于排序学生
int compare(const void a, const void b) {
Student *s1 = (Student *)a;
Student *s2 = (Student *)b;
return strcmp(s2->name, s1->name); // 按姓名降序排列
}
int main() {
int n, m;
scanf("%d %d", &n, &m); // 输入学生数和科目数
// 输入科目名称并创建科目索引映射
char subjects[10][100];
int i, j;
for (i = 0; i < m; i++) {
scanf("%s", subjects[i]);
}
// 创建学生数组
Student *students = (Student *)malloc(n * sizeof(Student));
// 输入学生数据
for (i = 0; i < n; i++) {
scanf("%s", students[i].name); // 输入学生姓名
students[i].rank = (int *)malloc((m + 1) * sizeof(int)); // 动态分配学生排名数组的内存
for (j = 0; j < m; j++) {
scanf("%d", &students[i].rank[j]); // 输入学生各科目排名
}
int totalScore = 0;
for (j = 0; j < m; j++) {
totalScore += students[i].rank[j]; // 计算总分
}
students[i].rank[m] = totalScore; // 将总分存入排名数组的最后一个元素
}
char subject[100];
scanf("%s", subject); // 输入用于排名的科目
int rankIdx = m; // 默认为总分排名
for (i = 0; i < m; i++) {
if (strcmp(subject, subjects[i]) == 0) {
rankIdx = i;
break;
}
}
// 根据排名排序学生
qsort(students, n, sizeof(Student), compare);
// 打印排序后的学生姓名
for (i = 0; i < n; i++) {
printf("%s ", students[i].name);
}
// 释放动态分配的内存
for (i = 0; i < n; i++) {
free(students[i].rank);
}
free(students);
return 0;
}
#### Java算法源码
import java.util.*;
class Student {
String name;
int[] rank;
public Student(String name, int[] rank) {
this.name = name;
this.rank = rank;
}
}
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 学生人数, 科目数量
int n = scanner.nextInt();
int m = scanner.nextInt();
scanner.nextLine(); // Consume newline
// key是科目名称,val是科目出现顺序的序号
Map<String, Integer> subjectRankIdx = new HashMap<>();
// 输入的m个科目
String[] subjects = scanner.nextLine().split(" ");
for (int i = 0; i < m; i++) {
subjectRankIdx.put(subjects[i], i);
}
List<Student> students = new ArrayList<>();
for (int i = 0; i < n; i++) {
String[] tmp = scanner.nextLine().split(" ");
// 学生姓名
String name = tmp[0];
// 学生给定科目的分数(m个)
int[] scores = new int[m];
for (int j = 0; j < m; j++) {
scores[j] = Integer.parseInt(tmp[j + 1]);
}
// 排名要素,0~m-1索引上的是给定科目成绩,m索引上的是总分
int[] rank = new int[m + 1];
System.arraycopy(scores, 0, rank, 0, m);
int totalScore = Arrays.stream(scores).sum();
rank[m] = totalScore;
students.add(new Student(name, rank));
}
// 用作排名的科目名称
String subject = scanner.nextLine();
// 用作排名的科目名称的排名要素序号, 如果用作排名的科目名称不存在,则按总分排名,对应序号是m
int rankIdx = subjectRankIdx.getOrDefault(subject, m);
// 按照排名要素排名,如果排名要素值相同,则按照学生姓名字典序排序
Collections.sort(students, new Comparator<Student>() {
@Override
public int compare(Student s1, Student s2) {
if (s1.rank[rankIdx] != s2.rank[rankIdx]) {
return Integer.compare(s2.rank[rankIdx], s1.rank[rankIdx]);
} else {
return s1.name.compareTo(s2.name);
}
}
});
// Print sorted student names
for (Student student : students) {
System.out.print(student.name + " ");
}
}
}
6 条评论
from functools import cmp_to_key
def main():
n, m = map(int, input().split())
kemu_list = input().split()[:m]
i = 0
chengji = []
while i < n:
my_list = input().split()
xingming = my_list[0]
mycj = list(map(int, my_list[1:]))
cj_dict = {}
cj_dict["xingming"] = xingming
cj_dict["total"] = sum(mycj)
for index in range(len(kemu_list)):
km = kemu_list[index]
cj_dict[km] = mycj[index]
chengji.append(cj_dict)
i += 1
kemu = input()
def my_sort(x, y): # 自定义排序函数
if kemu in kemu_list:
if x[kemu] == y[kemu]:
if x['xingming'] < y['xingming']: # 字符串不能相减,判断一下返回-1或者1
return -1
else:
return 1
else:
return y[kemu] - x[kemu]
else:
if x['total'] == y['total']:
if x['xingming'] < y['xingming']:
return -1
else:
return 1
else:
return y['total'] - x['total']
res = sorted(chengji, key=cmp_to_key(my_sort))
for r in res:
print(r['xingming'], end=' ')
if __name__ == '__main__':
main()
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]2024 C卷 100分序号题目知 识 点难易程度1密码输入检测数据结构/栈☆☆☆2分配土地几何问题☆☆☆3找座位逻辑分析☆☆☆4智能成绩表动态条件分析☆☆☆5内存冷热标记多条件排序☆☆☆6螺旋数字矩阵逻辑分析☆☆☆7围棋的气逻辑分析☆☆☆8分割平衡字符串逻辑分析☆☆☆9机器人搬砖二分法☆☆☆10转盘寿司数据结构/栈/单调栈☆☆☆11小明找位置二分法☆☆☆12提取字符串的最长合法简单数学表达式双指[...]
[...]真题目录序号题目 1密码输入检测 2分配土地 3找座位 4智能成绩表 5内存冷热标记 6螺旋数字矩阵 机器人搬砖 转盘寿司 提取字符串的最长合法简单数学表达式 2最富裕的小家庭 3最长字符串的长度(一) 开源项目热度榜单 游戏分组 虚拟理财游戏[...]