1.题目描述:点击打开链接
2.解题思路:本题是多关键字的排序题目,可以事先定义好优先级,然后利用一个优先队列来模拟“到来”和“进门”这2个过程,有2个地方需要小心:1.题目中输入的t,p需要事先排序;2.不要忘记处理最后一次开门时候的情况。
3.代码:
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define me(s) memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int, int> P;
const int N=150000+10;
struct Node
{
char name[210];
int val;
int rank;
void read(int i)
{
rank=i;
scanf("%s%d",name,&val);
}
bool operator<(const Node&rhs)const
{
if(val!=rhs.val)return val<rhs.val;
return rank>rhs.rank;
}
}a[N],b[N];
struct Open
{
int t,p;
void read()
{
scanf("%d%d",&t,&p);
}
bool operator<(const Open&rhs)const
{
return t<rhs.t;
}
}r[N];
int query[N];
Node ans[105];
int n,m,q;
void print()
{
for(int i=0;i<n;i++)
printf("%s %d\n",b[i].name,b[i].val);
}
void solve()
{
int st=0,cnt=0;
priority_queue<Node>pq;
for(int i=0;i<m;i++)
{
int pos=r[i].t,num=r[i].p;
for(int j=st;j<pos;j++)//“到达”
pq.push(a[j]);
while(num--) //“进门”
{
if(pq.empty())break;
b[cnt++]=pq.top();pq.pop(); //b数组存放进门的顺序
}
st=pos;
}
for(int j=st;j<n;j++)pq.push(a[j]); //处理最后一次开门
while(!pq.empty())
{
b[cnt++]=pq.top();pq.pop();
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&m,&q);
for(int i=0;i<n;i++)
a[i].read(i);
int st=0;
me(r);
for(int i=0;i<m;i++)
r[i].read();
sort(r,r+m); //事先要对t,p排序
for(int i=0;i<q;i++)
scanf("%d",&query[i]);
solve();
for(int i=0;i<q;i++)
printf("%s%c",b[query[i]-1].name," \n"[i==q-1]);
}
}