思路
一道很好的复习数据结构的题。
对于第 \(1\) 个问答(既第 \(2\) 种操作),我用一个小根堆(优先队列,\(\text{priority\_queue}\))来储存第 \(i\) 个盒子的卡牌。
对于第 \(2\) 个问答(既第 \(3\) 种操作),我用一个 \(\text{set}\) 来储存编号为 \(i\) 个卡牌在哪些盒子里。
由于 \(\text{set}\) 会自动去重,也会自动排序,所以直接存和输出了。
怎么存呢?
先看一下我开的变量:
set<int>q2[200010];
priority_queue<int,vector<int>,greater<int> >q1[200010],k;
其中 \(q_1[i]\) 表示第 \(i\) 个盒子里的卡牌(小根堆,升序排序),\(q_2[i]\) 表示编号为 \(i\) 个卡牌在的盒子的编号(也是升序排序),\(k\) 是输出用做过渡的。
设要将编号为 \(a\) 的卡牌放在编号为 \(b\) 的盒子里,则:
q1[b].push(a);
q2[a].insert(b);
看不懂的结合定义再理解一遍。
会存了,询问就直接输出了。
参考代码
#include<bits/stdc++.h>
using namespace std;
int n,q;
set<int>q2[200010];
priority_queue<int,vector<int>,greater<int> >q1[200010],k;
int main(){
scanf("%d%d",&n,&q);
while(q--){
int op;
scanf("%d",&op);
if(op==1){
int a,b;
scanf("%d%d",&a,&b);
q1[b].push(a);
q2[a].insert(b);
}
else if(op==2){
int a;
scanf("%d",&a);
while(!q1[a].empty()){
k.push(q1[a].top());
printf("%d ",q1[a].top());
q1[a].pop();
}
putchar('\n');
while(!k.empty()){
q1[a].push(k.top());
k.pop();
}
}
else{
int a;
scanf("%d",&a);
for(set<int>::iterator it=q2[a].begin();it!=q2[a].end();it++) printf("%d ",*it);
putchar('\n');
}
}
return 0;
}
标签:q1,q2,int,题解,scanf,200010,push,ABC298C
From: https://www.cnblogs.com/fengxiaoyi/p/17375602.html