HDU1873 看病要排队 —— 优先队列(STL)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1873
题解:
题目已经说出了解题方法:优先队列。但是之前没有学过优先队列,而且这题还是在现场赛做的。由于不会写优先队列的排序函数,所以自己想了个方法,觉得这种思维还可以,还是用优先队列。
队列priority_queue<int>q[4], 那么q是从大到小排列的,所以我就想将病人的优先级和编号放到一个int类型中,病人编号最大为2000,优先级最大为10。
由于排序的规则是先按优先级,再按编号,所以优先级的影响大,编号的影响小,那么可以将病人的信息整合到一个int中:102000。但是这样又出现了一个问题,
不同优先级的人先后解决了,但是相同优先级,不同编号的病人的顺序就搞反了。 相同优先级而编号小的病人理应排在前面,但却排在了后面,因为优先队列按从大到小排列。
怎么解决呢?由于编号的范围为1~2000,所以就想到了对编号进行对2000的取补,就是编号为k时,存进int里的,就应该是(2000-k),这样问题就解决了。
想想这种取补的方法应该挺好的。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<set> #include<string> #include<map> #include<vector> #include<queue> #define LL long long using namespace std; priority_queue<int>q[4]; char s[100]; int main() { int n,cnt,doc,pri,sum; while(scanf("%d",&n)!=EOF) { for(int i = 1; i<=3; i++) while(!q[i].empty()) q[i].pop(); cnt = 0; for(int i = 0; i<n; i++) { scanf("%s",s); if(s[0]=='I' && s[1]=='N') { scanf("%d%d",&doc,&pri); cnt++; sum = pri*10000 + (2000-cnt); q[doc].push(sum); } else { scanf("%d",&doc); if(q[doc].empty()) puts("EMPTY"); else { sum = q[doc].top(); q[doc].pop(); sum %= 10000; sum = 2000-sum; printf("%d\n",sum); } } } } return 0; }
优先队列:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #include<set> #include<string> #include<map> #include<vector> #include<queue> #define LL long long using namespace std; struct node { int pri,x; bool operator <(const node& t2) const { if(pri==t2.pri) return x>t2.x; return pri<t2.pri; } }; node now; priority_queue<node>q[4]; char s[100]; int main() { int n,cnt,doc,pri,sum; while(scanf("%d",&n)!=EOF) { for(int i = 1; i<=3; i++) while(!q[i].empty()) q[i].pop(); cnt = 0; for(int i = 0; i<n; i++) { scanf("%s",s); if(s[0]=='I' && s[1]=='N') { scanf("%d%d",&doc,&pri); now.pri = pri; now.x = ++cnt; q[doc].push(now); } else { scanf("%d",&doc); if(q[doc].empty()) puts("EMPTY"); else { now = q[doc].top(); q[doc].pop(); printf("%d\n",now.x); } } } } return 0; }