暴力
开一个priority_queue push pop ,
太慢了
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int maxn=10000;
vector <int> num;
int main() {
// freopen("a.txt","r",stdin);
int time;
scanf("%d",&time);
while ( time-- ) {
priority_queue<int> que;
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++) {
int t;
scanf("%d",&t);
que.push(t);
if( i%2 == 1) {
int len=i/2;
while ( len-- ) num.push_back(que.top()),que.pop();
printf("%d ",que.top());
while ( !num.empty() ) que.push(num.back()),num.pop_back();
}
}
printf("\n");
}
return 0;
}
对顶堆
- 分别用一个大根堆和小根堆,如序列
len=7
将[1,4]
放大根堆,其余放入小根堆 len%2 == 1
时肯定 两个堆大小差距为1,且大根堆的数<=
中位数X,小根堆的数>=x
- 每次判断数i与中位数
maxque.top()
的大小,i>x
则加入小堆,同理 - 维护
maxque.size()=minque.size()+1
这一性质,相互移动堆顶的数字
#include <iostream>
#include <queue>
using namespace std;
priority_queue<int> maxque;
priority_queue<int> minque;
int main() {
freopen("a.txt","r",stdin);
int t;
scanf("%d",&t);
while (t--) {
int n;
scanf("%d",&n);
for (int i=1;i<=n;i++) {
int x;
scanf("%d",&x);
if( maxque.empty() ) maxque.push(x);//第一个数先加入大堆
else {
//判断 该数与中位数的大小
if( x>maxque.top() ) minque.push(-x);
else maxque.push(x);
}
while ( maxque.size() < minque.size() ) {//大堆 < 小堆
int temp=minque.top();
minque.pop();
maxque.push(-temp);
}
while ( minque.size() < maxque.size()-1 ) {//小堆 比 大堆不止小1个
int temp=maxque.top();
maxque.pop();
minque.push(-temp);
}
if( i%2 == 1) printf("%d ",maxque.top() );//len为奇数时 输出平均数
}
printf("\n");
while ( !maxque.empty() ) maxque.pop();//清空堆
while ( !minque.empty() ) minque.pop();
}
return 0;
}
离线做法(链表+map)
- 排序后加入到链表,按输入的逆序删除并且记录中位数,然后逆序输出记录的中位数