看病要排队这个是地球人都知道的常识

 

归纳编程学习的感悟,
记录奋斗路上的点滴,
希望能帮到一样刻苦的你!
如有不足欢迎指正!
共同学习交流!
🌎欢迎各位→点赞 👍+ 收藏⭐ + 留言​📝

唯有付出,才有丰富的果实收获!

看病要排队这个是地球人都知道的常识。
不过经过细心的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

InputOutput
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 是所有事件的数量。

总结

该算法有效地利用了优先队列来管理每位医生的病人队列,并且通过全局计数器来唯一标识每个病人。这样可以保证每次诊治都是优先级最高的病人,并且在优先级相同的情况下选择了最早到来的病人。这种设计使得算法既简单又高效,能够很好地处理大规模的输入数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梵豪

你的鼓励将是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值