优先队列是STL中比较重要的一个部分,用起来非常方便,在很多排序题中要比sort一遍一遍排序快很多,它能根据自己定义顺序来进行排序。
主要的两种表达形式(其实还有其他的,这里就先列举两个):
第一种是用friend bool operator来写;
#include<stdio.h>
#include<iostream>
using namespace std;
#include<queue>
typedef struct node{
int num;
friend bool operator<(struct node a,struct node b) //这里的形式是固定的
{return a.num>b.num;}
}point;
第二种是用bool operator来写。
#include<stdio.h>
#include<iostream>
using namespace std;
#include<queue>
typedef struct node{
int num;
bool operator<(const node&b)const //这里的形式是固定的
{return num>b.num;}
}point;
要注意的是上面的两种都是从小到大来排顺序!!程序里面的大于小于号返回的是相反的,大于号是从小到大排序,小于是从大到小排序,自己定义优先级的时候一定要注意,跟其他地方的不太一样,记住就好了。
下面来看几道题
看病要排队—HDU - 1873
Problem
看病要排队这个是地球人都知道的常识。
不过经过细心的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
7
IN 1 1
IN 1 2
OUT 1
OUT 2
IN 2 1
OUT 2
OUT 1
2
IN 1 1
OUT 1
Sample Output
2
EMPTY
3
1
1
我这里用了三个优先队列,看起来比较麻烦,可以用一个优先队列组来写,会减少很多篇幅。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
const int maxn=25;
using namespace std;
typedef struct node{ //核心代码
int id;
int level;
friend bool operator<(struct node a,struct node b){
if(a.level!=b.level){
return a.level<b.level;
}
return a.id>b.id;
}
}point;
int main(){
int n;
while(scanf("%d",&n)!=EOF){
priority_queue<point>s1,s2,s3;
char str[maxn];
int count=1;
while(n--){
cin>>str;
if(str[0]=='I'){
int d;
cin>>d;
if(d==1){
point doctor1;
cin>>doctor1.level;
doctor1.id=count++;
s1.push(doctor1);
}
else if(d==2){
point doctor2;
cin>>doctor2.level;
doctor2.id=count++;
s2.push(doctor2);
}
else if(d==3){
point doctor3;
cin>>doctor3.level;
doctor3.id=count++;
s3.push(doctor3);
}
}
else{
int d;
cin>>d;
if(d==1){
if(!s1.empty()){
point p;
p=s1.top();
cout<<p.id<<endl;
s1.pop();
}
else{
cout<<"EMPTY"<<endl;
}
}
else if(d==2){
if(!s2.empty()){
point p;
p=s2.top();
cout<<p.id<<endl;
s2.pop();
}
else{
cout<<"EMPTY"<<endl;
}
}
else if(d==3){
if(!s3.empty()){
point p;
p=s3.top();
cout<<p.id<<endl;
s3.pop();
}
else{
cout<<"EMPTY"<<endl;
}
}
}
}
}
return 0;
}
Priority Queue—Aizu - ALDS1_9_C
Problem
A priority queue is a data structure which maintains a set S of elements, each of with an associated value (key), and supports the following operations:
- insert(S,k): insert an element kk into the set S
- extractMax(S): remove and return the element of S with the largest key
Write a program which performs the insert(S,k) and extractMax(S) operations to a priority queue
S. The priority queue manages a set of integers, which are also keys for the priority.
Input
Multiple operations to the priority queue S are given. Each operation is given by "insert k", "extract" or "end" in a line. Here, k represents an integer element to be inserted to the priority queue.
The input ends with "end" operation.
Output
For each "extract" operation, print the element extracted from the priority queue S in a line.
Constraints
- The number of operations ≤2,000,000
- 0≤k≤2,000,000,000
Sample Input 1
insert 8
insert 2
extract
insert 10
extract
insert 11
extract
extract
end
Sample Output 1
8
10
11
2
这道题就是很直接的用优先队列就直接写出来了,还是最主要最核心的就是那个代码。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
const int maxn=25;
using namespace std;
typedef struct node{
int num;
friend bool operator<(struct node a,struct node b){
if(a.num!=b.num){
return a.num<b.num;
}
}
}point;
int main(){
char s1[maxn];
priority_queue<point>s;
while(scanf("%s",s1)!=EOF){
if(s1[0]=='i'){
point p;
cin>>p.num;
s.push(p);
}
else if(s1[1]=='x'){
point p;
p=s.top();
s.pop();
cout<<p.num<<endl;
}
else{
break;
}
}
return 0;
}
很简单吧,去练几道题就掌握了。
HDU - 1509 HDU - 1263 先去试试这两道题吧,要是遇到什么问题可以留言给我,
第一次写博客,也是刚刚接触acm,要是有什么不对的地方请大家指正,谢谢大家了。