POJ 1442 Black Box
题目大意是给一串无序的整数 arr,然后有一串序列 vec,这个序列中的第每个数字代表前几个数,每个序列出现的位置代表第几小的数字,比如这个序列是{1,2,6,6},1 代表的arr中的前1个数中第一小的,2代表arr中前两个数第二小的,第一个6代表arr中前6个数字中第三小的,第二个6代表arr中前6个数第四小的,而且这组数字是升序的。
用最基础的暴力肯定会超时。
也是看着其他人的博客写的,用了优先队列,就是建立一个最大堆,一个最小堆,最大堆的堆顶要小于最小堆的堆顶,实时最大堆的元素个数和vec数组当前的下标有关,就是比如 进行到vec中的第二个数组的时候,最大堆只有一个元素,进行到第一个6的时候就有两个元素,最大堆中放的元素的要求是前N个数中最小的M个,最小堆里面放的是前个元素中减去最大堆中的元素剩下的元素。在每次求解的过程中,就是先将最小堆缺少的元素加入到最小堆中,比如 从2到6的时候,要加入4个元素,每次加入元素的时候最小堆的堆顶可能有些变化,如果最小堆的堆顶小于了最大堆的堆顶,两堆顶互换位置,这就保证了每次加入元素到最小后,最大堆的元素都是前N个中最小的,然后在元素全部加入完成后,将最小堆的堆顶加入到最大堆中,并输出。
#include <set>
#include <queue>
#include<algorithm>
#include <iostream>
#include<string.h>
#include<map>
#include<stack>
#include<string>
#include <stdio.h>
#include<sstream>
#include<utility>
using namespace std;
int arr[30000];
int main()
{
priority_queue<int>big;
priority_queue<int,vector<int>,greater<int> >small;
int n,m;
int a,b=0 ;
cin>>n>>m;
for(int i=0;i<n;i++)
cin>>arr[i];
for(int i=0;i<m;i++){
cin>>a;
for(int j=b;j<a;j++){
small.push(arr[j]);
if(!big.empty()&&big.top()>small.top()){
int c=big.top();
int d=small.top();
big.pop();
big.push(d);
small.pop();
small.push(c);
}
}
b=a;
cout<<small.top()<<endl;
big.push(small.top());
small.pop();
}
return 0;
}