题解
成绩排序
1 条题解
-
0
P4619 成绩排序(基础)
解题思路
这道题要把学生按成绩从高到低排序,成绩相同则按学号从小到大排,最后输出姓名和成绩。用结构体 Student 保存学号、姓名和成绩,学号就是输入顺序,从 1 开始编号。这就像老师给全班同学按分数排名,分数一样的同学,学号小的排在前面。
比较函数 cmp() 里先比成绩,成绩不同就按成绩从大到小排;成绩相同再比学号,学号小的排前面。这里要特别注意处理"成绩相同"的情况:样例中 qiqi 和 haha 都是 67.5 分,qiqi 学号是 1、haha 学号是 3,所以 qiqi 排在 haha 前面。如果只按成绩排序,这两个人的先后顺序就不确定,可能出错,所以必须把学号作为第二比较条件,保证次序稳定。
成绩是浮点数,输出时要保留一位小数。我们使用 cout 配合 fixed 和 setprecision(1),它采用"四舍五入"的舍入规则。比如输入 5.25 会输出 5.2,25.998 会输出 26.0,100 会输出 100.0,与标准答案完全一致。要注意不能用"乘 10 加 0.5 再取整"的简单方法,因为那种方法会把 5.25 变成 5.3,和标准答案对不上。
最后按排序后的顺序,每行输出姓名、一个空格和成绩。读取成绩时用 double 类型,姓名用 char 数组存储即可。
参考代码
// 成绩排序:按成绩从高到低排列,成绩相同按学号从小到大;成绩保留 1 位小数 #include <iostream> #include <iomanip> #include <algorithm> using namespace std; // 保存一名学生的信息 struct Student { int id; // 学号(按输入顺序 1~n) char name[30]; // 姓名 double score; // 成绩 }; // 自定义比较函数:成绩高的靠前,成绩相同学号小的靠前 bool cmp(const Student &a, const Student &b) { if (a.score != b.score) return a.score > b.score; return a.id < b.id; } int main() { int n; Student a[105]; cin >> n; for (int i = 0; i < n; i++) { cin >> a[i].name >> a[i].score; a[i].id = i + 1; // 输入顺序作为学号 } sort(a, a + n, cmp); // 按规则排序 cout << fixed << setprecision(1); // 成绩保留 1 位小数 for (int i = 0; i < n; i++) { cout << a[i].name << ' ' << a[i].score << endl; } return 0; }复杂度分析
sort() 排序的时间复杂度是 O(n log n),n 是学生人数(0 < n < 100)。结构体数组占用的空间是 O(n)。输出环节是 O(n)。整个程序运行非常快,轻松满足时间限制。
- 1