老题新解|病人排队
《信息学奥赛一本通》第159题:病人排队
题目描述
编写一个程序,将登记的病人按照以下原则排出看病的先后顺序:
- 老年人(年龄 ≥60\geq 60≥60 岁)比非老年人优先看病。
- 老年人按年龄从大到小的顺序看病,年龄相同的按登记的先后顺序排序。
- 非老年人按登记的先后顺序看病。
输入格式
第 111 行,输入一个小于 100100100 的正整数,表示病人的个数;
后面按照病人登记的先后顺序,每行输入一个病人的信息,包括:一个长度小于 101010 的字符串表示病人的 ID(每个病人的ID各不相同且只含数字和字母),一个整数表示病人的年龄,中间用单个空格隔开。
输出格式
按排好的看病顺序输出病人的 ID,每行一个。
输入输出样例 #1
输入 #1
5
021075 40
004003 15
010158 67
021033 75
102012 30
输出 #1
021033
010158
021075
004003
102012
大家好,我是莫小特。
这篇文章给大家带来《信息学奥赛一本通》中的第 159 题:病人排队。
一、题目描述
洛谷的题号是:B2160 病人排队
二、题意分析
这道题是信息学奥赛一本通练习题的第 159 题。
根据输入格式的描述,输入第一行为一个小于 100 的正整数,表示病人的个数,使用 int 类型。
int n;
cin>>n;
后面按照病人的登记先后顺序记录每个病人的信息,包含病人的 ID,每个病人的 ID 各不相同,并且只含数字和字母,所以可以使用字符串来存储,之后还需要输入病人的年龄,使用 int 类型,类型不同,所以使用结构体将两者结合起来。
struct bingren{string ID;//病人的IDint age;//病人的年龄
};
由于人数小于 100,所以需要定义一个结构体数组,元素个数大于 100 即可。
struct bingren{string ID;//病人的IDint age;//病人的年龄
}a[200];
结构体定义完成后,使用 for 循环将病人的 ID 和年龄输入。
for(int i=1;i<=n;i++)
{cin>>a[i].ID>>a[i].age;
}
输入完成后,我们来分析最后的输出,根据题目要求,我们要按排好看病顺序来输出病人的 ID,具体要求为:
(1)老年人(年龄 ≥60\geq 60≥60 岁)比非老年人优先看病。
(2)老年人按年龄从大到小的顺序看病,年龄相同的按登记的先后顺序排序。
(3)非老年人按登记的先后顺序看病。
所以需要对年龄进行判断,如果大于等于 60,则证明是老年人,老年人比非老年人优先看病,所以需要两两比较。
注意,比较的是 j 的值。
for(int i=n;i>=1;i--)
{for(int j=1;j<=i;j++){//年龄大于60岁 年龄从大到小进行排序if(a[j].age<a[j+1].age&&a[j+1].age>=60){swap(a[j],a[j+1]);//交换两个}}
}
最终输出病人的 id 即可。
for(int i=1;i<=n;i++)
{cout<<a[i].ID<<endl;
}
按照样例输入对数据进行验证。
符合样例输出,到网站提交测评。
测试通过!
三、完整代码
该题的完整代码如下:
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
struct bingren{string ID;//病人的IDint age;//病人的年龄
}a[200];
int main()
{int n;cin>>n;for(int i=1;i<=n;i++){cin>>a[i].ID>>a[i].age;}for(int i=n;i>=1;i--){for(int j=1;j<=i;j++){//年龄大于60岁 年龄从大到小进行排序if(a[j].age<a[j+1].age&&a[j+1].age>=60){swap(a[j],a[j+1]);//交换两个}}}for(int i=1;i<=n;i++){cout<<a[i].ID<<endl;}return 0;
}
四、总结
本题考察了自定义数据结构与排序策略,主要涵盖以下知识点:结构体(struct
)存储复合数据、稳定排序思想、自定义比较逻辑(将老年人优先且按年龄降序排序,非老年人保持登记顺序)。
需要掌握两种实现思路:一是按题目规则自定义 cmp
并用 sort
(注意稳定性或在比较中保留登记序号);二是可以先将老年人和非老年人分别收集,老年人按年龄降序(年龄相同按登记序)排序,最后拼接两段输出。
常见易错点 :
(1)直接对所有人按年龄降序排序,导致非老年人被重新排序,破坏了“非老年人按登记顺序”的要求。
(2)在 sort
比较函数中未考虑登记顺序(没有记录原始下标),导致年龄相同时丢失登记先后约束。
(3)错误使用不稳定排序而又没有在比较函数中处理登记序号,导致相同年龄老年人的相对顺序错乱。
(4)数组下标或循环边界处理不当(如越界访问 a[j+1]
)。
解题建议 :
(1)输入时记录每位病人的登记序号(原始下标),在比较函数中把它作为次级关键字以保证年龄相同时按登记顺序排序,或者用两个数组分别处理老年人和非老年人再合并,思路更清晰且避开稳定性问题。
(2)优先考虑可读性和正确性:写出排序准则的伪代码(先判定是否为老年人,再比较年龄,再比较登记序号),再把逻辑实现为 cmp
或分组排序。
(3)注意边界与输入格式检查,测试时用年龄恰好为 60、相同年龄多人的情况以及 n=1 等极值用例验证程序正确性。
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注我哦!
如果有更好的方法也可以在评论区评论哦,我都会看哒~
我们下集见~