【题目链接】
ybt 1183:病人排队
OpenJudge NOI 1.10 08:病人排队
【题目考点】
1. 排序
2. 多关键字排序
方法1:将多关键字的排序条件整合为单一排序条件
方法2:使用稳定的排序算法进行多趟排序
【解题思路】
解法1:老年人和年轻人分别排序
设结构体保存一个人的信息:id和年龄。设两个数组分别保存老年人和年轻人的信息。对保存老年人信息的数组按年龄降序排序,由于年龄相同的要按登记顺序排序,所以要选择稳定的排序算法。而后分别顺序输出两个数组中数组元素的ID。
解法2:整合为一个排序条件
输入时,保存每个人的登记序号(即这是第几个人)
使用sort或stable_sort排序,设比较函数,传入两个人的信息
- 如果一个是老年人一个是非老年人,老年人排在前
- 如果两个人都是老年人,那么年龄大的排在前面。如果年龄相同,序号小的排在前面。
- 如果两个都是非老年人,登记序号小的排在前面。
以上条件可以简化为:
- 如果两人都是年轻人,或如果两个人都是老年人且年龄相等,那么登记序号小的排在前面。
- 如果两人年纪不等,无论两人都是老年人,还是一老一少,都应该是年纪更大的排在前面。
【题解代码】
解法1:老年人和非老年人分别排序
- 使用STL stable_sort函数排序
#include<bits/stdc++.h>
using namespace std;
#define N 105
struct Peo
{
char id[10];
int age;
};
bool cmp(Peo a, Peo b)
{
return a.age > b.age;
}
int main()
{
int n, io = 0, iy = 0;//io:old数组中元素个数 iy:young数组中元素个数
cin >> n;
Peo old[N], young[N], a;//old:老年人信息 young:年轻人信息
for(int i = 1; i <= n; ++i)
{
cin >> a.id >> a.age;
if(a.age >= 60)
old[++io] =a;
else
young[++iy] = a;
}
stable_sort(old+1, old+1+io, cmp);
for(int i = 1; i <= io; ++i)
cout << old[i].id << endl;
for(int i = 1; i <= iy; ++i)
cout << young[i].id << endl;
return 0;
}
- 插入排序
#include<bits/stdc++.h>
using namespace std;
#define N 105
struct Peo
{
char id[10];
int age;
};
int main()
{
int n, io = 0, iy = 0;//io:old数组中元素个数 iy:young数组中元素个数
cin >> n;
Peo old[N], young[N], a;//old:老年人信息 young:年轻人信息
for(int i = 1; i <= n; ++i)
{
cin >> a.id >> a.age;
if(a.age >= 60)//加入到老年人数组,做插入排序
{
old[++io] =a;
for(int j = io; j > 1; j--)//插入排序
{
if(old[j].age > old[j-1].age)
swap(old[j], old[j-1]);
else
break;
}
}
else
young[++iy] = a;
}
for(int i = 1; i <= io; ++i)
cout << old[i].id << endl;
for(int i = 1; i <= iy; ++i)
cout << young[i].id << endl;
return 0;
}
解法2:整合为一个比较条件
- 使用STL sort函数,记录个人序号,比较函数意义直接
#include<bits/stdc++.h>
using namespace std;
#define N 105
struct Peo
{
char id[10];
int age, num;//num:序号
};
bool cmp(Peo a, Peo b)
{
if(a.age >= 60 && b.age >= 60)//如果都是老人
{
if(a.age == b.age)//如果年龄相同
return a.num < b.num;//序号小的在前面
else
return a.age > b.age;//年龄大的在前面
}
else if(a.age < 60 && b.age < 60)//如果都不是老人
return a.num < b.num;//序号小的在前面
else//一个老人一个不是老人
return a.age > b.age;//老人年龄大,在前面
}
int main()
{
int n;
cin >> n;
Peo a[N];//a:各人人信息
for(int i = 1; i <= n; ++i)
{
cin >> a[i].id >> a[i].age;
a[i].num = i;
}
sort(a+1, a+1+n, cmp);
for(int i = 1; i <= n; ++i)
cout << a[i].id << endl;
return 0;
}
- 使用STL stable_sort函数,记录个人序号,更简洁的比较函数
#include<bits/stdc++.h>
using namespace std;
#define N 105
struct Peo
{
char id[10];
int age, num;//num:序号
};
bool cmp(Peo a, Peo b)
{
if(a.age < 60 && b.age < 60 || a.age == b.age)//如果都不是老人 或都是老人且年龄相等
return a.num < b.num;//序号小的排在前面
else//至少有一个老人且年龄不等
return a.age > b.age;//无论是两老人还是一老一年轻,都是年纪更大的更靠前
}
int main()
{
int n;
cin >> n;
Peo a[N];//a:各人人信息
for(int i = 1; i <= n; ++i)
{
cin >> a[i].id >> a[i].age;
a[i].num = i;
}
stable_sort(a+1, a+1+n, cmp);
for(int i = 1; i <= n; ++i)
cout << a[i].id << endl;
return 0;
}