题目链接: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;
}