top1编程
← 返回题目
题解

成绩排序

1 条题解

  • 0
    @ 2026-8-5 21:47:33

    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