1 条题解
-
0
思路
用三个平行数组分别存每个病人的 ID、年龄、登记序号:
char id[100][15]:ID(字符串)int age[100]:年龄int order_[100]:登记顺序(第几个登记的)
排序规则整理成一个核心问题:病人 i 应该排在病人 j 前面吗? 写成一个函数
before(i, j),返回 1 表示 i 应排前面:- i 是老人(≥60)而 j 不是 → i 在前;
- j 是老人而 i 不是 → j 在前;
- 两个都不是老人 → 按登记顺序,先登记的在前;
- 两个都是老人 → 年龄大的在前;年龄相同则先登记的在前。
然后用冒泡排序:相邻两个人如果"后面的应该排前面",就交换。交换时三个数组要同步交换,保证一个人的 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
- 上传者
吉公网安备22010402001496号