HDU 5437by cyl优先队列

本文解析了HDU5437问题,通过使用优先队列实现了一个关于礼物价值和访客顺序的问题。需要根据特定时间允许最多数量的高价值礼物持有者进入。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HDU 5437

题意:

​ 有个人要过生日,有k个朋友来拜访,但是他家里实在是有点小,只能依次让朋友进门,有m个特定的时间,每次可以进入p个人,每一个朋友来会带礼物,价值为v。主人还是比较贪心的,他让朋友进入的条件是谁的礼物价值大谁先进,价值相等就按照拜访的顺序进入。

思路:

​ 可以看出是细节题,考察了对优先队列的掌握,问题在于要猜测出题人的思路,或者说是算法不错但是无法AC的时候,多思考是不是在时间、顺序、思路上有问题。

  • 坑点在于输入m个开门的时间需要排序。
#include<cstdio>
#include<queue>
#include<iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 150005;

struct ss
{
    int x;  //time
    int y;  //value
    char name[205];
    ss() {}
    ss(int xx,int yy)
    {
        x=xx;
        y=yy;
    }
    bool operator<(const ss& b)const
    {
        if(y == b.y) {
            return x > b.x;
        }
        return y<b.y;
    }
}s[maxn];
struct Ans
{
    char name[205];
}ans[maxn];
struct Door
{
    int t,p;
}door[maxn];
int k,m,q;
bool cmp1(Door a,Door b)
{
    return a.t < b.t;
}
int main()
{
//    freopen("in.txt","r",stdin);
    priority_queue<ss>que1;
    int ncase;
    scanf("%d",&ncase);
    while(ncase--) {
        scanf("%d%d%d",&k,&m,&q);
        for(int i = 1;i <= k; i++) {
            scanf("%s %d",s[i].name,&s[i].y);
            s[i].x = i;
        }
        int time = 1;
        int pos = 0;
        while(!que1.empty()) {
            que1.pop();
        }
        for(int i = 1;i <= m; i++) {
            scanf("%d%d",&door[i].t,&door[i].p);
        }
        sort(door+1,door+1+m,cmp1);
        for(int i = 1;i <= m; i++) {
            int t = door[i].t;
            int p = door[i].p;
            if(time <= t) {
                for(;time <= t && time <= k; time++) {
                    que1.push(s[time]);
                }
            }
            while(p > 0 && !que1.empty()) {
                strcpy(ans[++pos].name,que1.top().name);
                que1.pop();
                p--;
            }
        }
        for(;time <= k; time++) {
            que1.push(s[time]);
        }
        while(!que1.empty()) {
            strcpy(ans[++pos].name,que1.top().name);
            que1.pop();
        }
        for(int i = 1;i <= q; i++) {
            int temp;
            scanf("%d",&temp);
            if(i == 1) {
                printf("%s",ans[temp].name);
            }
            else printf(" %s",ans[temp].name);
        }
        printf("\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值