POJ 3784 Running Median (最大最小堆)

最大最小堆动态求中位数

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

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

 

分析:

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

刚好符合堆的特点。

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

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

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

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

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

 

插入排序也可以诶- -

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<vector>
 8 #include<queue>
 9 #include<map>
10 #include<set>
11 #include<stack>
12 
13 using namespace std;
14 
15 typedef long long ll;
16 
17 int a[5010];
18 priority_queue<int> q1;
19 priority_queue<int,vector<int>,greater<int> > q2;
20 
21 int main()
22 {
23     int T,cas,m,x;
24     scanf("%d",&T);
25     while(T--)
26     {
27         while(!q1.empty()) q1.pop();
28         while(!q2.empty()) q2.pop();
29         int c = 0;
30         memset(a,0,sizeof(a));
31         scanf("%d%d",&cas,&m);
32         for(int i=1;i<=m;i++)
33         {
34             scanf("%d",&x);
35             if(q1.empty())
36                 q1.push(x);
37             else
38             {
39                 if(x>q1.top())
40                     q2.push(x);
41                 else q1.push(x);
42             }
43 
44             while(q1.size()<q2.size())
45             {
46                 int t = q2.top();
47                 q2.pop();
48                 q1.push(t);
49             }
50 
51             while(q2.size()<q1.size()-1)
52             {
53                 int t = q1.top();
54                 q1.pop();
55                 q2.push(t);
56             }
57 
58 
59             if(i&1)
60             {
61                 a[c++] = q1.top();
62             }
63         }
64         printf("%d %d\n",cas,m/2+1);
65         for(int i=0;i<m/2+1;i++)
66         {
67             if(i==0)
68             {
69                 printf("%d",a[i]);
70                 continue;
71             }
72             if(i%10==0 && i!=0)
73                 printf("\n%d",a[i]);
74             else printf(" %d",a[i]);
75         }
76         if((m/2+1)%10) printf("\n");
77     }
78     return 0;
79 }
View Code

 

posted @ 2015-04-12 22:59  fukan  阅读(889)  评论(0编辑  收藏  举报