本文主要是介绍看病要排队这个是地球人都知道的常识,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
归纳编程学习的感悟,
记录奋斗路上的点滴,
希望能帮到一样刻苦的你!
如有不足欢迎指正!
共同学习交流!
🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言📝
唯有付出,才有丰富的果实收获!
看病要排队这个是地球人都知道的常识。
不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么少)同时看病。而看病的人病情有轻重,所以不能根据简单的先来先服务的原则。所以医院对每种病情规定了10种不同的优先级。级别为10的优先权最高,级别为1的优先权最低。医生在看病时,则会在他的队伍里面选择一个优先权最高的人进行诊治。如果遇到两个优先权一样的病人的话,则选择最早来排队的病人。
现在就请你帮助医院模拟这个看病过程。
Input
输入数据包含多组测试,请处理到文件结束。
每组数据第一行有一个正整数N(0<N<2000)表示发生事件的数目。
接下来有N行分别表示发生的事件。
一共有两种事件:
1:"IN A B",表示有一个拥有优先级B的病人要求医生A诊治。(0<A<=3,0<B<=10)
2:"OUT A",表示医生A进行了一次诊治,诊治完毕后,病人出院。(0<A<=3)
Output
对于每个"OUT A"事件,请在一行里面输出被诊治人的编号ID。如果该事件时无病人需要诊治,则输出"EMPTY"。
诊治人的编号ID的定义为:在一组测试中,"IN A B"事件发生第K次时,进来的病人ID即为K。从1开始编号。
Sample
Input | Output |
---|---|
7 IN 1 1 IN 1 2 OUT 1 OUT 2 IN 2 1 OUT 2 OUT 1 2 IN 1 1 OUT 1 | 2 EMPTY 3 1 1 |
#include <iostream>
#include <vector>
#include <string>
#include <queue>
using namespace std;// 定义病人结构体
struct Patient {int id; // 病人的编号int priority; // 病人的优先级// 构造函数Patient(int id, int priority) : id(id), priority(priority) {}// 自定义比较运算符,用于priority_queue中的元素比较// 返回true如果当前对象应该排在参数对象之前friend bool operator<(const Patient &a, const Patient &b) {if (a.priority == b.priority) { // 如果优先级相同return a.id > b.id; // 则选择编号较小(即先来)的病人}return a.priority < b.priority; // 否则选择优先级较高的病人}
};int main() { ios::sync_with_stdio(false); // 禁用C风格I/O同步,提高效率cin.tie(0); // 解绑cin与cout的绑定,避免缓冲区延迟int n; // 事件总数while (cin >> n && n != 0) { // 处理多组测试数据priority_queue<Patient> doctors[4]; // 初始化四位医生的优先队列,索引0不用int eventCount = 0; // 初始化病人的编号计数器// 读取并处理每个事件while(n--) {string command; // 命令类型cin >> command;if (command == "IN") { // 如果是“入队”命令int doctor, priority; // 医生编号和病人的优先级cin >> doctor >> priority;// 创建一个新的病人对象,并将其加入对应医生的队列Patient newPatient(++eventCount, priority);doctors[doctor].push(newPatient); } else if (command == "OUT") { // 如果是“出队”命令int doctor; // 医生编号cin >> doctor;if (!doctors[doctor].empty()) { // 如果医生队列不为空// 输出当前队列最前面的病人编号cout << doctors[doctor].top().id << endl;// 移除当前队列最前面的病人doctors[doctor].pop(); } else { // 如果医生队列为空cout << "EMPTY\n"; // 输出“EMPTY”}}}}return 0;
}
算法分析
数据结构
Patient
结构体: 包含病人的优先级priority
和编号id
。priority_queue<Patient>
: 每位医生有一个优先队列,用于存储等待诊治的病人。优先队列中的元素按优先级降序排列,如果优先级相同,则按编号升序排列(即先来的病人优先)。vector<priority_queue<Patient>> doctors
: 一个向量,用于存储三位医生各自的优先队列。索引0位置不使用,因为医生编号从1开始。
输入处理
- 读取事件数量
eventCount
:每一组测试数据的第一行包含发生事件的数量。 - 处理每个事件:对于每个事件,根据命令类型执行相应的操作。
命令处理
- IN 命令 (
command == 1
):- 读取医生编号
doctor
和病人的优先级priority
。 - 增加全局病人数
patientId
计数器,为新病人分配一个唯一的ID。 - 创建一个
Patient
对象,包含给定的优先级和新的ID。 - 将
Patient
对象推入对应医生的优先队列中。
- 读取医生编号
- OUT 命令 (
command != 1
):- 读取医生编号
doctor
。 - 如果医生的队列不为空,则:
- 输出队列顶部病人的ID。
- 弹出队列顶部的病人。
- 否则,输出 "EMPTY" 表示没有病人等待诊治。
- 读取医生编号
时间复杂度
- 插入病人到优先队列的时间复杂度是 O(log N),其中 N 是队列中的病人数量。
- 从优先队列中弹出病人的时间复杂度也是 O(log N)。
- 因此,对于每个事件,平均时间复杂度为 O(log N)。
空间复杂度
- 最坏情况下,所有的病人都进入队列,空间复杂度为 O(N),其中 N 是所有事件的数量。
总结
该算法有效地利用了优先队列来管理每位医生的病人队列,并且通过全局计数器来唯一标识每个病人。这样可以保证每次诊治都是优先级最高的病人,并且在优先级相同的情况下选择了最早到来的病人。这种设计使得算法既简单又高效,能够很好地处理大规模的输入数据。
这篇关于看病要排队这个是地球人都知道的常识的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!