您的位置:首页 > 其它

POJ 3784 Running Median (最大最小堆)

2015-04-12 22:59 225 查看
最大最小堆动态求中位数

题意:输入M个数,当已输入的个数为奇数个时输出此时的中位数。

一共有M/2+1个中位数要输出,每一行10个。

分析:

用两个优先队列来模拟最大最小堆。中位数是x,就是有一半数比x小,一半数比x大。

刚好符合堆的特点。

用一个从大到小排序的优先队列q1来模拟小于x的数。

从小到大排序的优先队列q2来模拟大于x的数。

动态维护两个优先队列的元素个数。q1.size()=q2.size() 输入的数为偶数个时,

q1.size()=q2.size()+1 输入的数为奇数个时。

每次要输出的中位数恰好是q1.top().

插入排序也可以诶- -

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<stack>

using namespace std;

typedef long long ll;

int a[5010];
priority_queue<int> q1;
priority_queue<int,vector<int>,greater<int> > q2;

int main()
{
int T,cas,m,x;
scanf("%d",&T);
while(T--)
{
while(!q1.empty()) q1.pop();
while(!q2.empty()) q2.pop();
int c = 0;
memset(a,0,sizeof(a));
scanf("%d%d",&cas,&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
if(q1.empty())
q1.push(x);
else
{
if(x>q1.top())
q2.push(x);
else q1.push(x);
}

while(q1.size()<q2.size())
{
int t = q2.top();
q2.pop();
q1.push(t);
}

while(q2.size()<q1.size()-1)
{
int t = q1.top();
q1.pop();
q2.push(t);
}

if(i&1)
{
a[c++] = q1.top();
}
}
printf("%d %d\n",cas,m/2+1);
for(int i=0;i<m/2+1;i++)
{
if(i==0)
{
printf("%d",a[i]);
continue;
}
if(i%10==0 && i!=0)
printf("\n%d",a[i]);
else printf(" %d",a[i]);
}
if((m/2+1)%10) printf("\n");
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: