题解
登记学生信息
1 条题解
-
0
P4677 登记学生信息(基础)
解题思路
第一步,定好排队规则。 规则有两条:先按年级从低到高排;年级一样时,再按年龄从大到小排。这就是"双关键字排序",像运动会入场:先按班级排队,同班同学再按个子高矮排。
第二步,把信息打包。 每个同学有年级 grade 和年龄 age 两个信息,用结构体 Stu 装在一起,开数组 students 存下所有同学。
第三步,写比较函数。 比较函数 cmp 里先比年级:x.grade < y.grade 时 x 排前面;如果年级相同,再比年龄:x.age > y.age 时 x 排前面。两个关键字都要比,漏掉第二个关键字,年级相同的同学就排不好了。
第四步,排序输出。 sort(students, students + n, cmp) 排完后,按顺序每行输出一个同学的年级和年龄。
想一想生活里的例子。 排队时先按班级排队,同班同学再按个子从高到矮站好,两个规则一次到位。
用例子验证。 输入三行:(2,10)、(1,9)、(1,11)。先比年级:1 年级的两个人排到 2 年级前面;年级相同时再比年龄:1 年级里 11 岁的大于 9 岁。所以输出顺序是 1 11、1 9、2 10,两个规则都满足。
边界情况: n 小于 100,数组开 105 足够;两个关键字要按顺序比较,先年级、后年龄,不要写反。
参考代码
// P4677 登记学生信息:按年级从低到高,年级相同按年龄从大到小 #include <iostream> #include <algorithm> using namespace std; struct Stu { int grade; // 年级 int age; // 年龄 }; bool cmp(const Stu &x, const Stu &y) { if (x.grade != y.grade) return x.grade < y.grade; // 年级低的在前 return x.age > y.age; // 年级相同,年龄大的在前 } Stu students[105]; int main() { int n; cin >> n; for (int i = 0; i < n; i++) { cin >> students[i].grade >> students[i].age; } sort(students, students + n, cmp); for (int i = 0; i < n; i++) { cout << students[i].grade << ' ' << students[i].age << endl; } return 0; }复杂度分析
sort 排序 n 个学生,时间复杂度 O(n log n),n < 100,很快。空间复杂度 O(n),存每个学生的年级和年龄。
- 1