top1编程
← 返回题目
题解

平均分排序

1 条题解

  • 0
    @ 2026-8-5 22:12:18

    P4629 平均分排序(基础)

    解题思路

    n 名学生每人有学号、语文、数学、英语四科,要求按平均分从低到高排序。因为每个人都是三科成绩,平均分 = 总分 ÷ 3,总分越低的平均分越低,所以只要按总分从小到大排序即可。题目也保证每个学生的平均分都不相同,所以不需要处理并列。读入时算好总分存进结构体,sort() 按总分升序排序,比较函数里直接比较总分的大小。

    举一个具体的例子:学生 4 总分 30 最低,平均分 10.0 排最前面;学生 3 总分 170,平均分 56.7 排第二;学生 5 总分 180,平均分 60.0;学生 1 总分 190,平均分 63.3;学生 2 总分 278,平均分 92.7 排在最后。排序后依次输出学号和平均分。

    输出时平均分要保留 1 位小数,我们先把总分除以 3.0 转成 double,再用 fixed 和 setprecision(1) 输出一位小数。平均分各不相同,所以不会出现并列需要额外规则的情况。

    参考代码

    // 用途:按三科平均分从低到高排序,输出学生的学号和平均分(保留1位小数)。
    #include <iostream>
    #include <algorithm>
    #include <iomanip>
    using namespace std;
    
    struct Student {
        int id;             // 学生的学号
        int sum;            // 学生的三科总分
    };
    
    // 排序规则:总分越低平均分越低,排前面
    bool cmp(const Student& a, const Student& b) {
        return a.sum < b.sum;
    }
    
    int main() {
        int n;                              // 学生人数
        cin >> n;                           // 读入学生人数
        Student a[105];                     // 保存学生信息
    
        for (int i = 0; i < n; i++) {       // 依次读入学生信息
            int chinese, math, english;     // 当前学生的语文、数学、英语成绩
            cin >> a[i].id >> chinese >> math >> english; // 读入学号和三科成绩
            a[i].sum = chinese + math + english;           // 计算三科总分
        }
        sort(a, a + n, cmp);                // 按平均分从低到高排序
    
        for (int i = 0; i < n; i++) {       // 按排序结果逐人输出
            double avg = a[i].sum / 3.0;    // 平均分 = 总分除以3
            cout << a[i].id << ' ' << fixed << setprecision(1) << avg << '\n'; // 保留1位小数
        }
        return 0;                           // 程序结束
    }
    

    复杂度分析

    sort() 时间 O(n log n),n 最大 100。程序用结构体数组保存学生,空间 O(n)。平均分保留 1 位小数,用 fixed 配合 setprecision(1) 时,整数位为 0 也会正确输出 0.0 这样的格式,不会省略小数部分。排序时直接比较总分,因为每个人都是三门课,总分和平均分的大小顺序完全一致,先算总分再排序既准确又简单。这道题读入的是四个整数(学号加三科成绩),学号在第一个位置,读入时顺序不能写反,否则学号和成绩会错位。

    • 1