信息学奥赛一本通 1183:病人排队 | OpenJudge NOI 1.10 08:病人排队

【题目链接】

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;
}
  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息学奥赛一本通1255:迷宫问题是一个关于迷宫的问题。这个问题要求通过广搜算法来解决迷宫问题,找到走出迷宫的路径。具体来说,迷宫可以看成是由n×n的格点组成,每个格点只有两种状态, "." 和 "#" 。其中 "." 代表可通行的路径,"#" 代表不可通行的墙壁。通过广搜算法,我们可以搜索从起点到终点的路径,找到一条合法的路径即可。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [信息学奥赛一本通 1255:迷宫问题 | OpenJudge NOI 2.5 7084:迷宫问题](https://blog.csdn.net/lq1990717/article/details/124721407)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [c++信息学奥赛一本通1215题解](https://download.csdn.net/download/Asad_Yuen/87357807)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [信息学奥赛一本通(1255:迷宫问题)](https://blog.csdn.net/lvcheng0309/article/details/118879231)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值