题解
平均分排序
1 条题解
-
0
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