F : [算法竞赛进阶指南]动态中位数
Time Limit:2 Sec Memory Limit:128 MiB
Back Submit Edit
Description
读入一个整数序列,每当读入的整数个数为奇数时,输出已读入的整数构成的序列的中位数。
Input
第一行输入包含一个整数P,(1≤P≤1000),为测试数据的数量。
每个测试数据的第一行为一个奇数十进制整数M(1≤M≤9999),M为要处理的有符号整数的总数。
每个测试数据的第二行包含M个数
Output
对于每个数据集,在一行输出所有的中位数(输出的中位数个数应该是M加一的一半)。
Sample Input
3
9
1 2 3 4 5 6 7 8 9
9
9 8 7 6 5 4 3 2 1
23
23 41 13 22 -3 24 -31 -11 -8 -7 3 5 103 211 -311 -45 -67 -73 -81 -99 -33 24 56
Sample Output
1 2 3 4 5
9 8 7 6 5
23 23 22 22 13 3 5 5 3 -3 -7 -3
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
int main(){
int T;
cin>>T;
while(T--)
{
int n;
cin>>n;
priority_queue<int> max_heap,min_heap;
//由于优先队列是默认降序的
//所以本体构建了两个优先队列
//一个用原数据存储是降序的
//令一个先取负在入队则在不考虑符号的情况下是升序的
//所以max_heap用于存储降序队列包括中位数
//min_heap用于存储升序队列
//所以整体的存储数应该这样看
//降序的来看先由min_heap队尾元素往前走,走到队首
//在由max_heap队首向队尾走就可以达到整体降序的目的
for(int i=0;i<n;i++)
{
int t;
cin>>t;
max_heap.push(t);
if(min_heap.size()&&-min_heap.top()<max_heap.top())
{//当升序队列有元素的前提下,因为还要进行元素的判断
//为了保持整体的降序形式
//来维护两个队列
int a=-min_heap.top(),b=max_heap.top();
min_heap.pop(),max_heap.pop();
min_heap.push(-b),max_heap.push(a);
}
if(max_heap.size()>min_heap.size()+1){
//当降序队列大于升序队列+1时为求中位数
//降序队列队首要向升序队列移动
int a=-max_heap.top();
max_heap.pop();
min_heap.push(a);
}
if (!(i & 1))
printf("%d ", max_heap.top());
//当为奇数时输出
}
}
return 0;
}