hdu 5437

26 篇文章 0 订阅

题目概述

你邀请了K个朋友参加派对,每个朋友都有名字name,来的时候都带了价值v的礼物,但是你屋子太小没法让他们一次都进来,于是你让他们在门口排队,期间你会开M次门,每次开门发生在第T个朋友到来之后,你会让至多P个朋友进来,在门口排队的朋友按照带的礼物价值降序排列,价值相同的先到的排前面,当最后一个朋友到门口时时,你会敞开大门让所有朋友按排队顺序进来,这里有Q次询问,每次询问第q个进来的朋友的姓名

时限

2000ms/3000ms

输入

第一行整数times,其后times组数据,每组数据第一行整数K,M,Q,其后K行,每行一个字符串name,一个整数v,其后M行,每行两个整数T,P,其后一行Q个整数q

限制

1<=times<=15;1<=K<=150000;0<=M<=K;1<=Q<=100;1<=T<=K;0<=P<=K;1<=v<=1e8
至多2组数据的K>10000,name长度<=200,仅含英文字母

输出

每组数据输出在一行,Q个字符串,为询问结果

样例输入

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

样例输出

Sorey Lailah Rose
Sorey Lailah Rose Mikleo Maltran

讨论

水题,没什么可说的

题解状态

920MS,35864K,1278 B,G++

题解代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 150004
#define memset0(a) memset(a,0,sizeof(a))
struct It//用于优先队的朋友的结构 也是存储开门顺序的结构
{
    int n, v;//朋友到达的序号和礼物价值 开门放进来朋友数和开门发生的时刻
    bool operator<(const It &b) const
    {
        return v != b.v ? v < b.v : n > b.n;
    }
} its[MAXN];//开门顺序
int K, M, Q;//朋友总数 开门次数 询问次数
int index, value[MAXN], stk[MAXN], top;//朋友到达的时间戳 朋友礼物价值 存储朋友进来先后的栈及其栈顶
char names[MAXN][204];//朋友的名字
void fun()
{
    index = 1;
    for (int p = 0; p < K; p++) {//录入人名 到达先后 礼品价格
        int v;
        scanf("%s%d", names[index], &v);//input
        value[index++] = v;
    }
    for (int p = 0; p < M; p++)//录入开门
        scanf("%d%d", &its[p].v, &its[p].n);//input
    its[M].v = its[M].n = K;//额外添加当所有朋友到齐时的敞开大门
    sort(its, its + M);//按时刻先后排序
    priority_queue<It>pq;
    index = 1;
    for (int p = 0; p < M + 1; p++) {
        int T, P;//开门时刻 放进来人数
        T = its[p].v, P = its[p].n;
        while (index <= T)
            pq.push(It{index, value[index++]});//这些人都在门口等着
        for (int p = 0; p < P&&!pq.empty(); p++) {
            stk[top++] = pq.top().n;//但只有一部分人能进来
            pq.pop();
        }
    }
    for (int p = 0; p < Q; p++) {
        int q;
        scanf("%d", &q);//input
        if (p)
            printf(" ");//output
        printf("%s", names[stk[q - 1]]);//output
    }
    printf("\n");//output
}
int main(void)
{
    //freopen("nb_cin.txt", "r", stdin);
    //freopen("nb_cout.txt","w",stdout);

    int times;
    scanf("%d", &times);//input
    while (times--) {
        scanf("%d%d%d", &K, &M, &Q);//input
        fun();
        top = 0;
    }
}

EOF

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值