优先队列的模拟
支持3种操作
insert x :将x插入到最小堆中。
getMin x :获取最小堆的堆顶,要求最小值为x
removeMin:将最小堆的堆顶弹出。
题目给出了一些操作,不一定合法,往里再添加一些操作使得所有的操作都合法,
求添加操作最少的情况并按序输出全部操作(新添加的和已存在的)
题解:
优先队列模拟最小堆
insert x向队列里加入x
removeMin时将堆顶top给pop(如果堆为空,则任意入队一个数然后再pop)
getMin x: 1. 如果堆为空,则加入x
2. 不为空, top() = x;直接getMin x
3.不为空但top()>x,加入x
4. 不为空但top() < x 一直removeMin,直到top() >= x 或堆为空 (之后按1,2,3方法处理)
#include<iostream>
#include<queue>
#include<string>
#include<cstdio>
#include<cstring>
using namespace std ;
const int maxn = 1e6 +10 ;
const string opers[3 ] = {"insert" ,"getMin" ,"removeMin" };
string ans[maxn];
int nums[maxn];
int cnt;
typedef priority_queue<int ,vector <int > ,greater<int > > pqueue;
void qclear(pqueue &qu)
{
pqueue eempty;
qu = eempty;
}
void getans(int pos,int num)
{
ans[cnt] = opers[pos];
nums[cnt++] = num;
}
void print()
{
cout <<cnt<<endl;
for (int i=0 ;i<cnt;i++)
{
if (ans[i][0 ]=='r' ) cout <<ans[i]<<endl;
else cout <<ans[i]<<" " <<nums[i]<<endl;
}
}
int main()
{
std ::ios::sync_with_stdio(false );
int n;
pqueue qu;
while (cin >>n)
{
cnt = 0 ;
string op;
int num;
qclear(qu);
for (int i=1 ;i<=n;i++)
{
cin >>op;
if (op[0 ] == 'i' ) {
cin >>num;
qu.push(num);
getans(0 ,num);
}
else if (op[0 ] == 'r' ) {
if (qu.empty()) getans(0 ,0 );
else qu.pop();
getans(2 ,0 );
}
else {
cin >>num;
if (qu.empty()) {
qu.push(num);
getans(0 ,num);
}
else {
int now = qu.top();
if (now > num)
{
getans(0 ,num);
qu.push(num);
}
else if (now < num)
{
while (!qu.empty() && qu.top() < num){
qu.pop();
getans(2 ,0 );
}
if (qu.empty()||qu.top() > num) qu.push(num),getans(0 ,num);
}
}
getans(1 ,num);
}
}
print();
}
return 0 ;
}