hdoj5437(icpc2015长春网络赛)Alisha‘s Party 优先队列

Princess Alisha invites her friends to come to her birthday party. Each of her friends will bring a gift of some value vv, and all of them will come at a different time. Because the lobby is not large enough, Alisha can only let a few people in at a time. She decides to let the person whose gift has the highest value enter first.

Each time when Alisha opens the door, she can decide to let pp people enter her castle. If there are less than pp people in the lobby, then all of them would enter. And after all of her friends has arrived, Alisha will open the door again and this time every friend who has not entered yet would enter.

If there are two friends who bring gifts of the same value, then the one who comes first should enter first. Given a query nn Please tell Alisha who the nn−th person to enter her castle is.

Input Format

The first line of the input gives the number of test cases, TT, where 1≤T≤151≤T≤15.

In each test case, the first line contains three numbers k, mk, m and qq separated by blanks. kk is the number of her friends invited where 1≤k≤150,0001≤k≤150,000. The door would open mmtimes before all Alisha's friends arrive where 0≤m≤k0≤m≤k. Alisha will have qq queries where 1≤q≤1001≤q≤100.

The ii−th of the following kk lines gives a string BiBi​, which consists of no more than 200200English characters, and an integer vi, 1≤vi≤108vi​, 1≤vi​≤108, separated by a blank. BiBi​ is the name of the ii−th person coming to Alisha's party and BiBi​ brings a gift of value vivi​.

Each of the following mm lines contains two integers t(1≤t≤k)t(1≤t≤k) and p(0≤p≤k)p(0≤p≤k)separated by a blank. The door will open right after the tt−th person arrives, and Alisha will let pp friends enter her castle.

The last line of each test case will contain qqnumbers n1, ..., nqn1​, ..., nq​ separated by a space, which means Alisha wants to know who are the n1−th, ..., nq−thn1​−th, ..., nq​−th friends to enter her castle.

Note: there will be at most two test cases containing n>10000n>10000.

Output Format

For each test case, output the corresponding name of Alisha's query, separated by a space.

样例输入

1
5 2 3
Sorey 3
Rose 3
Maltran  3
Lailah 5
Mikleo  6
1 1
4 2
1 2 3

样例输出

Sorey Lailah Rose

题目解释:Alisha在第t个朋友到达的时候,会打开门让p个朋友进来,如果当前未进去的朋友数<p,则让他们都进来,且所携带value较大者优先进入,想要找到第i个进入的人,输出他的名字

题目思路:常规思路想的话,因为要让value大者先入,所以在每次轮到那几个朋友进入的情况下都需要对这几个朋友排序,且要记住他们的进入的序号,这样的话代码不仅会相当复杂,而且肯定会超时。

可以考虑使用优先队列,同时要注意考虑好最好如何输出名字。

ac代码:peo是arrive时的顺序,num是进入时的顺序,最后输出[num对应的peo].name即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#define maxn 150010
using namespace std;
struct node{
    int pos;
    int value;
    char name[205];
    friend bool operator < (node a,node b)
    {
        if(a.value==b.value)  return a.pos>b.pos;
        else return a.value<b.value;//notice that in priority_queue operator's
                               //funtion is opposite
    }
}a,b[maxn];//a is used to push into the priority_queue,b is used for the putin data
struct dd{
    int t,p;//when the t-th friend come,open door and let p friends come in
}door[maxn];
bool cmp(dd a,dd b)
{
    return  a.t<b.t;//in case that door[i].t>door[i+1].t
}
int order[maxn];//record the final order of friends to come in,then print
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        priority_queue<node> y;
        int k,m,q,i,j;//k=sum of frends;m=numbers of open door;q=sum of querie;
        scanf("%d%d%d",&k,&m,&q);
        for(i=1;i<=k;i++)
            scanf("%s%d",b[i].name,&b[i].value);
        for(i=1;i<=m;i++)
            scanf("%d%d",&door[i].t,&door[i].p);
        sort(door+1,door+1+m,cmp);
        int peo=1,num=1;//already come in peo person
        for(i=1;i<=m;i++)
        {
            while(peo<=door[i].t)
            {
                strcpy(a.name,b[peo].name);
                a.value=b[peo].value;
                a.pos=peo;//the peo-th arrive
                peo++;
                y.push(a);
            }
            while(door[i].p&&!y.empty())
            {
                order[num++]=y.top().pos;//the num-th come in is the peo-th arrive
                                        //notice that num may not queal peo
                y.pop();
                door[i].p--;
            }
        }
            while(peo<=k)//if there still left some friend outside
            {
                strcpy(a.name,b[peo].name);
                a.value=b[peo].value;
                a.pos=peo;
                peo++;
                y.push(a);
            }
            while(!y.empty())
            {
                order[num++]=y.top().pos;
                y.pop();
            }
        int n;
        for(i=0;i<q;i++)
        {
            scanf("%d",&n);
            printf("%s",b[order[n]].name);
            if(i!=q-1)
                printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值