HDU-5437-模拟-优先队列

18 篇文章 0 订阅

以前模拟题总是不好好应对,看完题解就喵懂,正向思维就gg。
其实比赛的时候连题都没读懂,但是觉得应该是一个模拟。
关键就是根据钱和来的地方进行排序吧。
先输入,然后在根据他们来到的时间和金钱。
根据开门的次数确定吞吐数量。
有一个技巧,就是设定当第n个人来到时,设定应该进去的人数为n
这样就可以解决最后那些还没进去的人的去留问题了。感觉特别好,
不然还得保存当前进人的值。
加一个入栈出栈的过程。
2 结构体初始化干嘛,。。。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <vector>
using namespace std;
/*用优先队列的方法来求,
一个 记录他的时间,一个记录他的礼物
然后用优先队列,第几个到了之后
并且最后当所有的开门次数完了还有人没进来时,
而暴力处理的时候更是巧妙,
设置当最后一个人来的时候,把n个人全部都放进去。就可以解决这个问题。
*/
const int maxn=150005;
struct Node
{  int v;
   int tim;
    Node(){};
    Node(int _a,int _b)
    {  v=_a;
        tim=_b;
    }
   bool operator <(const Node&a)const
   {  if(v==a.v) return tim>a.tim;//时间之间越短越先
       return v<a.v;//越有钱越先来,好婊
   }
};
struct nod
{  char  w[305];
   int v;
   int tim;

}node[150005];
int nex[150005];
void init()
{   memset(nex,0,sizeof(nex));
    memset(node,0,sizeof(node));


}
int main()
{  ios::sync_with_stdio(false);
     int t;
    while(cin>>t)
    {int n,m,qe;
    int a,b,q;

    while(t--)
    {   cin>>n>>m>>qe;
        init();
        for(int i=1;i<=n;i++)
         {   cin>>node[i].w;
            cin>>node[i].v;
            node[i].tim=i;
         }
         /*for(int i=1;i<=n;i++)
         {  cout<<node[i].w<<endl;

         }*/
        for(int i=1;i<=m;i++)
        {   cin>>a>>b;
             nex[a]+=b;
        }
        nex[n]=n;
        priority_queue<Node>que;
        int ans[150005];
        int tt=1;
        //cout<<node[4].w<<"????"<<endl;
        for(int i=1;i<=n;i++)
        {   que.push(Node(node[i].v,i));
           while(nex[i]--)
           {  if(que.size()==0)break;
               Node s=que.top();
              que.pop();//按照钱和时间来排序
             ans[tt++]=s.tim;
           }
        }
        //cout<<node[4].w<<"@@@"<<endl;
        int ccc=1;
        for(int i=1;i<=qe;i++)
        {    //scanf("%d",&q);
          cin>>q;
            if(ccc==1)
            {cout<<node[ans[q]].w;ccc++;}
             //cout<<ans[q]<<"!!!"<<endl;
            else
            cout<<" "<<node[ans[q]].w;

             }
         cout<<endl;
    }

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值