题目链接:https://vjudge.net/problem/241634/origin
题目大意:一个人过生日, 有k个朋友来送礼, 但是房子太小, 每次等到第t个人来到后, 开一次门, 让p个人进来, 送礼的价值v越大的优先进入, 价值相同就先到的先入, 总共开m次门, 主人有q次询问, 问第n个进来的人是谁?
核心思想:用优先队列模拟一下就好啦(主要问题就在元素为结构体的优先队列怎么写啦)
代码:
#include<bits/stdc++.h>
using namespace std;
//typedef pair<int, string> P;
const int M=200000;
struct P
{
string n;
int v;
int t;
friend bool operator < (const P a, const P b)//重载运算符,这样才能判断优先级啊
{
if(b.v == a.v)return a.t > b.t;
return a.v < b.v;
}
}p[M];
struct door//题目的一个坑点, 要保证门是按顺序开的
{
int t, p;
}dd[M];
bool cmp(door a, door b)//结构体排序。。。
{
return a.t < b.t;
}
string ss[M];
int main()
{
cin.sync_with_stdio(false);//加速cin、cout,不开超时妥妥的; 还有一个要注意的是, 开了这个,就不能用scanf了, 否则要像我一样找一早上的bug都发现不了
priority_queue<P>pq;
int T;
cin>>T;
while(T--)
{
while(!pq.empty())
pq.pop();
int k, m, q;
cin>>k>>m>>q;
for(int i=1; i<=k; ++i)
{
cin>>p[i].n>>p[i].v;
p[i].t=i;
}
int top=1, tot=0, now=1;
for(int i=1; i<=m; ++i)
{
cin>>dd[i].t>>dd[i].p;
}
sort(dd+1, dd+m+1, cmp);//给开门顺序从小到大排序,亲测没有相同开门的坑点
for(int i=1; i<=k; ++i)
{
pq.push(p[i]);
while(i==dd[now].t && now <= m)
{
for(int j=1; j<=dd[now].p && !pq.empty(); ++j)
{
ss[++tot]=pq.top().n;//用ss数组存下每个人是第几个进入的
pq.pop();
}
++now;
}
}
while(!pq.empty())//别忘了最后有些人没进来啊
{
P np=pq.top();
pq.pop();
ss[++tot]=np.n;
}
for(int i=0; i<q; ++i)
{
int qq;
cin>>qq;
if(i!=0)
cout<<" ";
cout<<ss[qq];
}
cout<<endl;
}
return 0;
}
希望以后我查bug会越来越快啊。。。