首页 > 技术文章 > hdu1873 看病要排队[优先队列]

hardcoreYutian 2019-08-05 13:39 原文

题目地址

hdu1873

题干


代码和解释

本题使用了优先队列,优先队列的特点是每次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神

推荐阅读