NCSTOJ: 动态中位数 (优先队列应用)

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;
	
	
	}

猜你喜欢

转载自blog.csdn.net/qq_42635159/article/details/89367749