题目:http://acm.hdu.edu.cn/showproblem.php?pid=5437
题意:一个派对,每次开一次门,开m次门,每次开门选择一定数量的人进来,先进来的满足带的礼物价值最大,当价值相同时要求来的早的人先进,最后一次全都可以进,给定查询,问第几个进去的人的名字。
题解:用优先队列模拟门口的情况,每次取出最符合条件的人进行标记
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
char name[150050][205];
struct Bt
{
int value;
int condition;
bool operator < (Bt c) const//要求价值不同时价值优先,相同时来的时间优先
{
if(c.value==value)
{
return c.condition<condition;
}
return value<c.value;
}
};
Bt b[150050];
typedef struct
{
int l;
int num;
}LR;
bool compare (LR a,LR b)
{
return a.l<b.l;
}
LR face[150050];
int ans[150050];
int main()
{
int t;
int k,m,q;
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d",&k,&m,&q);
for(int i=1;i<=k;i++)
{
scanf("%s %d",name[i],&b[i].value);
b[i].condition=i;
}
for(int i=1;i<=m;i++)输入第几个人来时开门,进去几个
{
scanf("%d %d",&face[i].l,&face[i].num);
}
sort(face+1,face+m+1,compare);
priority_queue<Bt> que;
int cnt=1;
int cont=1;
for(int i=1;i<=k;i++)//模拟
{
que.push(b[i]);
if(i==face[cnt].l && cnt<=m)
{
for(int j=1;j<=face[cnt].num && !que.empty();j++)
{
ans[cont++]=que.top().condition;
que.pop();
}
cnt++;
}
}
while(!que.empty())//最后全部都进去
{
ans[cont++]=que.top().condition;
que.pop();
}
for(int i=1;i<=q;i++)
{
int p;
scanf("%d",&p);
if(i!=q) printf("%s ",name[ans[p]]);
else printf("%s\n",name[ans[p]]);
}
}
return 0;
}