【题目描述】
某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前55名学生发奖学金。期末,每个学生都有33门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学 排在前面,这样,每个学生的排序是唯一确定的。
任务:先根据输入的33门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。注意,在前55名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:
7 279 5 279
这两行数据的含义是:总分最高的两个同学的学号依次是77号、55号。这两名同学的总分都是279279(总分等于输入的语文、数学、英语三科成绩之和),但学号为7的学生语文成绩更高一些。如果你的前两名的输出数据是:
5 279 7 279
则按输出错误处理,不能得分。
【输入】
第1行为一个正整数n,表示该校参加评选的学生人数。
第2到n+1行,每行有33个用空格隔开的数字,每个数字都在0到100之间。第j行的3个数字依次表示学号为j−1的学生的语文、数学、英语的成绩。每个学生的学号按照输入顺序编号为l∼n(恰好是输入数据的行号减1)。
所给的数据都是正确的,不必检验。
【输出】
共有5行,每行是两个用空格隔开的正整数,依次表示前5名学生的学号和总分。
【输入样例】
6 90 67 80 87 66 91 78 89 91 88 99 77 67 89 64 78 89 98
【输出样例】
6 265 4 264 3 258 2 244 1 237
【提示】
输入输出样例2】
输入:
8 80 89 89 88 98 78 90 67 80 87 66 91 78 89 91 88 99 77 67 89 64 78 89 98
输出:
8 265 2 264 6 264 1 258 5 258
【限制】
50%的数据满足:各学生的总成绩各不相同;
100%的数据满足: 6≤n≤300。
【样例分析】
输入样例
6
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
这表示有6名学生参加评选,其语文、数学、英语的成绩分别如上所示。
输入样例解析
- 学生1的成绩为:90(语文)、67(数学)、80(英语),总分为237。
- 学生2的成绩为:87(语文)、66(数学)、91(英语),总分为244。
- 学生3的成绩为:78(语文)、89(数学)、91(英语),总分为258。
- 学生4的成绩为:88(语文)、99(数学)、77(英语),总分为264。
- 学生5的成绩为:67(语文)、89(数学)、64(英语),总分为220(此学生不在前五名中,所以在这里忽略)。
- 学生6的成绩为:78(语文)、89(数学)、98(英语),总分为265。
排序过程
根据题目要求的排序规则(总分降序 > 语文成绩降序 > 学号升序),排序后的学生及其总分为:
- 学生6:265分
- 学生4:264分
- 学生3:258分
- 学生2:244分
- 学生1:237分
输出样例
6 265
4 264
3 258
2 244
1 237
这意味着,在排序后,总分最高的前五名学生依次是学号为6、4、3、2、1的学生,他们的总分分别是265、264、258、244、237。
直观描述
- 学生6以微弱优势(总分265)位列第一,他们的英语成绩在所有学生中是最高的。
- 紧随其后的是学生4,他在数学上表现出色,总分264。
- 第三名是学生3,他们在数学和英语上都有很好的成绩,总分258。
- 第四名是学生2,总分244。
- 第五名是学生1,尽管他的语文成绩最高,但因为其他两科相对较低,所以总分为237。
【解题思路】
-
定义学生结构体:首先定义一个学生结构体
Student
,包含学号、三科成绩、总分作为成员。 -
读取输入:读取学生人数
n
,接着读取每位学生的三科成绩,并计算总分。 -
排序:根据题目要求,需要先按总分从高到低排序,总分相同则按语文成绩从高到低排序,如果总分和语文成绩都相同,按学号从小到大排序。这可以通过自定义排序函数实现。
-
输出前五名学生的信息:根据排序后的结果,输出前五名学生的学号(加1以还原为输入中的编号)和总分。
【代码实现】
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
// 定义学生结构体
struct Student {
int id; // 学号
int scores[3]; // 三科成绩
int total; // 总分
};
// 自定义排序规则
bool compare(const Student &a, const Student &b) {
if (a.total != b.total) return a.total > b.total; // 总分降序
if (a.scores[0] != b.scores[0]) return a.scores[0] > b.scores[0]; // 语文成绩降序
return a.id < b.id; // 学号升序
}
int main() {
int n;
cin >> n;
vector<Student> students(n);
// 读取数据
for (int i = 0; i < n; ++i) {
students[i].id = i + 1; // 学号从1开始
cin >> students[i].scores[0] >> students[i].scores[1] >> students[i].scores[2];
students[i].total = students[i].scores[0] + students[i].scores[1] + students[i].scores[2]; // 计算总分
}
// 排序
sort(students.begin(), students.end(), compare);
// 输出前五名学生信息
for (int i = 0; i < 5; ++i) {
cout << students[i].id << " " << students[i].total << endl;
}
return 0;
}
标签:07NOIP,语文,成绩,排序,学生,89,总分,奥赛,1938
From: https://blog.csdn.net/lan_in/article/details/137399651