1 条题解

  • 0
    @ 2026-8-18 12:03:40

    思路

    用三个平行数组分别存每个病人的 ID、年龄、登记序号:

    • char id[100][15]:ID(字符串)
    • int age[100]:年龄
    • int order_[100]:登记顺序(第几个登记的)

    排序规则整理成一个核心问题:病人 i 应该排在病人 j 前面吗? 写成一个函数 before(i, j),返回 1 表示 i 应排前面:

    1. i 是老人(≥60)而 j 不是 → i 在前;
    2. j 是老人而 i 不是 → j 在前;
    3. 两个都不是老人 → 按登记顺序,先登记的在前;
    4. 两个都是老人 → 年龄大的在前;年龄相同则先登记的在前。

    然后用冒泡排序:相邻两个人如果"后面的应该排前面",就交换。交换时三个数组要同步交换,保证一个人的 ID、年龄、序号始终绑在一起。

    代码

    #include <stdio.h>
    #include <string.h>
    
    char id[100][15];   // 病人ID
    int age[100];       // 年龄
    int no[100];        // 登记顺序
    
    // 判断病人 i 是否应该排在病人 j 前面
    int before(int i, int j) {
        if (age[i] >= 60 && age[j] < 60) return 1;   // i 老人,j 不是:i 在前
        if (age[i] < 60 && age[j] >= 60) return 0;   // j 老人,i 不是:j 在前
        if (age[i] < 60 && age[j] < 60)              // 都不是老人
            return no[i] < no[j];                    // 按登记顺序
        if (age[i] == age[j])                        // 同龄老人
            return no[i] < no[j];                    // 按登记顺序
        return age[i] > age[j];                      // 老人年龄大的在前
    }
    
    // 交换两个病人(三个数组同步交换)
    void swap(int i, int j) {
        char tmp[15];
        strcpy(tmp, id[i]); strcpy(id[i], id[j]); strcpy(id[j], tmp);
        int t = age[i]; age[i] = age[j]; age[j] = t;
        t = no[i]; no[i] = no[j]; no[j] = t;
    }
    
    int main() {
        int n;
        scanf("%d", &n);
    
        for (int i = 0; i < n; i++) {
            scanf("%s %d", id[i], &age[i]);
            no[i] = i;               // 记录登记顺序
        }
    
        // 冒泡排序
        int flag = 1;
        while (flag) {
            flag = 0;
            for (int i = 0; i < n - 1; i++) {
                if (before(i + 1, i)) {   // 后面的人应该排前面 → 交换
                    swap(i, i + 1);
                    flag = 1;
                }
            }
        }
    
        for (int i = 0; i < n; i++)
            printf("%s\n", id[i]);
        return 0;
    }
    

    运行样例

    输入:

    5
    021075 40
    004003 15
    010158 67
    021033 75
    102012 30
    

    排序过程(按"before"规则比较):

    • 两位老人:021033(75 岁,第 4 登记)、010158(67 岁,第 3 登记)。75 > 67,所以 021033 排最前;
    • 之后按登记顺序排非老人:021075、004003、102012。

    输出:

    021033
    010158
    021075
    004003
    102012
    

    易错点

    • 60 岁算老人(>= 60),59 岁不算,这是最常见的边界错误。
    • 交换时三个数组必须一起换,漏掉任何一个都会导致 ID 和年龄"张冠李戴"。
    • 字符串交换用 strcpy,不能直接赋值(C 里的字符串不是基本类型)。
    • 同龄老人要按登记顺序:靠登记序号 no 来比较,而不是依赖排序算法是否稳定。

    信息

    ID
    7
    时间
    1000ms
    内存
    256MiB
    难度
    1
    标签
    递交数
    2
    已通过
    1
    上传者