题目大意
公主阿莉莎邀请她的朋友参加她的生日宴会,但是大厅不够大,所以就不能一次性让所有的人进来,只能允许部分人进来,同时部分人中手里拿的礼物价值最大的最先进来(我去,以前也这样搞!!!)。于是下面给T组数据,k表示有有多少个朋友被邀请,m表示门会开几次,q表示会询问多少次第几个进来的人是谁。
题目分析
给出了每个人到来的时间,首先很明显要对所有人进行排序,这里需要注意的就是重载小于STL中priority_queue需要注意的问题,价值大的肯定排在前面,相同价值需要注意是编号小的排在前面。于是进行模拟,通过一个二维数组存储所有的人按顺序进去的名字,询问时对应输出就可以了。同时需要注意有可能门不会开,但是所有人都来了,门最终还是会打开,所有人都会进去,就是最好处理一下门已经开了m次之后还没有进去的人就可以了。具体见代码。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int maxn = 150005;
struct Node //注意重载运算符的时候需要注意相同的价值先来的先进去
{
char name[204];
int val,id;
bool operator < (const Node temp)const
{
if(val == temp.val) return id > temp.id;
else return val < temp.val;
}
}node[maxn];
struct Ret //需要对m组数据进行排序,因为给出的时间不一定是递增的,本以为会超时,看了一下时间给了3s
{
int t,p;
bool operator < (const Ret temp) const
{
return t < temp.t;
}
}ret[maxn];
char str[maxn][204]; //用于存每个人按顺序到来的名字
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int k,m,q,query;
scanf("%d%d%d", &k, &m, &q);
for(int i = 1; i <= k; i++)
{
scanf("%s %d", node[i].name, &node[i].val);
node[i].id = i;
}
for(int i = 0; i < m; i++)
scanf("%d%d", &ret[i].t, &ret[i].p);
sort(ret, ret+m);
priority_queue <Node> pq; //优先队列,价值最大的优先
while(!pq.empty()) pq.pop();
int from = 1,flag = 1;
memset(str, '\0', sizeof(str));
for(int i = 0; i < m; i++)
{
for(int j = from; j <= ret[i].t; j++)
pq.push(node[j]);
from = ret[i].t+1;
for(int j = 1; j <= ret[i].p; j++)
{
if(!pq.empty())
{
Node temp = pq.top();
pq.pop();
strcpy(str[flag++], temp.name);
}
else
break;
}
}
for(int i = from; i <= k; i++)
pq.push(node[i]);
while(!pq.empty()) //有可能m等于0,但是最后有朋友都来了时会把门打开,需要处理这种情况
{
Node temp = pq.top();
pq.pop();
strcpy(str[flag++], temp.name);
}
for(int i = 1; i <= q; i++) //输出时的格式同样需要注意
{
scanf("%d", &query);
if(i != q)
printf("%s ", str[query]);
else
printf("%s\n", str[query]);
}
}
return 0;
}