hdu1873 看病要排队[优先队列]

题目地址

hdu1873

题干

1559979-20190805105743760-1378720510.png
1559979-20190805105822519-839563198.png

代码和解释

本题使用了优先队列,优先队列的特点是每次push和pop操作后自动排序,把优先级最高的放在队列首,出对时优先级最高的出队。
优先队列默认数字大的优先级高,但也可以自定义优先级,如下面这种方式:

struct node{
    int num;
    friend bool operator<(node n1,node n2){
        return n1.num>n2.num;//num值小的优先级高
    }
};

在这里, operator 后面是 < ,意思是 return 的布尔值为真时 n1<n2 ,即 n1 的优先级低于 n2 。所以在这里, n1.num 的值比 n2.num 的值大则 n1 的优先级比 n2的优先级低,也就是num值大的优先级低。如果 operator 后面的符号为 > ,自然就反过来了。

本题我们对病人优先级的规定与病人的编号和自带优先级有关。priority_queue<node>q[4];可以理解为优先队列数组,有4个优先队列。把这个操作放在第一个 while 循环的内部可以代替每组样例开头的队列清空操作。
c++代码如下:

#include<iostream>
#include<queue>
#include<string.h>
using namespace std;
struct node{
    int pri;
    int num;
    friend bool operator<(node n1,node n2){
        if(n1.pri==n2.pri) return n1.num>n2.num;//自带优先级相同的,编号小的优先 
        else return n1.pri<n2.pri;//自带优先级不同的,优先级大的优先 
    }
}pat;//一个病人结构体,含他的自带优先级和编号信息 
int main()
{

    int N;
    char io[4];
    int doc;//医生的号码 
    int prio;//病人的自带优先级 
    int numb;//病人的编号 
    while(~scanf("%d",&N)){
        numb=0;//每组样例编号清零 
        priority_queue<node> d[4];//d[1]、d[2]、d[3]三个优先队列存储三个医生要看的病人结构体 
        while(N--){
            scanf("%s",io);
            if(strcmp(io,"IN")==0){
                numb++;//有病人来看病时编号加一 
                scanf("%d%d",&doc,&prio);
                pat.num=numb;
                pat.pri=prio;
                d[doc].push(pat);
            }
            else if(strcmp(io,"OUT")==0){
                scanf("%d",&doc);
                if(!d[doc].empty()){
                    printf("%d\n",d[doc].top().num);
                    d[doc].pop();
                }
                else{
                    printf("EMPTY\n");
                }
            }
        }
    }
    return 0; 
} 

参考

优先队列的操作:

  • q.top();//返回具有最高优先级的元素值,但不删除该元素
  • q.pop();//删除最高优先级元素
  • q.push(item);//插入新元素

  • STL中,优先队列是用二叉堆实现的,往队列中push入一个数或pop一个数,复杂度是O(logn)
    hdu1873 - Ice_Crazy的专栏
    学些优先队列 - Bin神

转载于:https://www.cnblogs.com/hardcoreYutian/p/11301688.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值