top1编程
← 返回题目
题解

登记学生信息

1 条题解

  • 0
    @ 2026-8-5 23:52:33

    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