题目地址
题干
代码和解释
本题使用了优先队列,优先队列的特点是每次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神