top1编程
← 返回题目
题解

平均分排序

1 条题解

  • 0
    @ 2026-8-6 1:50:12

    P4617 平均分排序(基础)

    解题思路

    这道题要把学生按平均分从低到高排序,并保留一位小数输出。平均分里面藏着小技巧,分四步讲清楚。

    第一步,发现一个"偷懒"的办法。 平均分 = 三门总分 ÷ 3,每名学生都是除以同一个 3,所以"平均分低的"和"总分低的"完全等价。干脆不比平均分,直接比总分,全程都是整数运算,又准又快,还不用怕浮点数比较出误差。

    第二步,用结构体装好学号和总分。 结构体 Student 保存学号和总分。读入三门成绩后立刻算出总分存进去,排序时按总分从小到大排。题目保证每个学生的平均分都不相同,所以总分也不会相同,不需要处理并列。

    第三步,用整数技巧算一位小数。 输出要保留一位小数,直接用 double 有浮点误差风险。换整数思路:总分除以 3 的商是整数部分;余数只有 0、1、2,分别对应小数点后的 .0、.333……、.666……,四舍五入到一位就是 .0、.3、.7。代码用 (score % 3 * 10 + 1) / 3 算出十分位。比如总分 170:170/3 = 56 余 2,(2×10+1)/3 = 7,输出 56.7;样例第 1 个学生总分 190:190/3 = 63 余 1,(1×10+1)/3 = 3,输出 63.3;再比如总分 180:180/3 = 60 余 0,(0×10+1)/3 = 0,输出 60.0。

    第四步,排序后输出。 用 sort() 按总分从小到大排好,然后逐个输出学号、空格、平均分和换行。

    **回顾总结。**这道题有两个巧劲:一是"平均分低等于总分低",所以排序只比整数总分;二是"一位小数用余数算",把浮点误差彻底消灭在整数运算里。不管总分多大,商和余数都能用整除和取余一步算出来,记住余数 0、1、2 对应 .0、.3、.7,再套公式就能稳稳输出。

    参考代码

    // 平均分排序:按三门成绩平均分从低到高排列学生,输出平均分(保留1位小数)
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    // 保存一名学生的学号和三门成绩总分
    struct Student {
        int id;           // 学号
        int score;        // 三门总分
    };
    
    // 自定义比较函数:总分(即平均分)从低到高
    bool cmp(const Student &a, const Student &b) {
        return a.score < b.score;
    }
    
    // 输出平均分(保留 1 位小数),用整数运算避免浮点误差
    void printAvg(int score) {
        cout << score / 3 << '.';                    // 整数部分
        cout << (score % 3 * 10 + 1) / 3;            // 十分位:四舍五入
    }
    
    int main() {
        int n;
        Student students[105];
        cin >> n;
        for (int i = 0; i < n; i++) {
            int chinese, math, english;
            cin >> students[i].id >> chinese >> math >> english;
            students[i].score = chinese + math + english;   // 计算总分
        }
        sort(students, students + n, cmp);   // 按平均分从低到高排序
        for (int i = 0; i < n; i++) {
            cout << students[i].id << ' ';
            printAvg(students[i].score);
            cout << endl;
        }
        return 0;
    }
    

    复杂度分析

    排序用 sort(),时间复杂度是 O(n log n),n 不超过 100。结构体数组占用的空间是 O(n)。整数四舍五入的每一步都是 O(1),而且完全避免了浮点误差,运行速度非常快。

    • 1