POJ 3784.Running Median
2015-07-16
问题简述:
动态求取中位数的问题,输入一串数字,每输入第奇数个数时求取这些数的中位数。
原题链接:http://poj.org/problem?id=3784
解题思路:
求取中位数的方法常常想到使用堆来实现:取一个大顶堆,一个小顶堆,使大顶堆的堆顶记录中位数,因此,要时刻保持大顶堆堆顶元素小于小顶堆堆顶元素,且大顶堆元素个数等于小顶堆元素个数或等于小顶堆元素个数加一。
以下有两种堆得实现方法:
一:直接使用STL中的函数(make_heap,push_heap,pop_heap,sort_heap)实现堆;
二:使用优先队列(priority_queue)实现堆;
方法一源码:
1 /* 2 OJ: POJ 3 ID: 3013216109 4 TASK: 3784.Running Median 5 LANG: C++ 6 NOTE: 堆(STL) 7 */ 8 #include <cstdio> 9 #include <algorithm> 10 using namespace std; 11 12 const int MAX=10005; 13 int a[MAX],b[MAX],c[MAX]; 14 15 bool cmp(int a,int b) { 16 return a>b; 17 } 18 19 int main() 20 { 21 int t,n,m,x; 22 scanf("%d",&t); 23 while(t--) { 24 scanf("%d %d",&n,&m); 25 int a_len=0,b_len=0,k=0,i=0; 26 while(m--) { 27 i++; 28 scanf("%d",&x); 29 if(a_len==0) { 30 a[0]=x; 31 c[k++]=x; 32 a_len++; 33 continue; 34 } 35 36 if(x<=a[0]) { 37 a[a_len++]=x; 38 push_heap(a,a+a_len); 39 } 40 else { 41 b[b_len++]=x; 42 push_heap(b,b+b_len,cmp); 43 } 44 45 while(a_len>b_len+1) { 46 b[b_len++]=a[0]; 47 pop_heap(a,a+a_len); 48 a_len--; 49 push_heap(b,b+b_len,cmp); 50 } 51 while(a_len<b_len) { 52 a[a_len++]=b[0]; 53 pop_heap(b,b+b_len,cmp); 54 b_len--; 55 push_heap(a,a+a_len); 56 } 57 58 if(i%2==1) 59 c[k++]=a[0]; 60 } 61 62 printf("%d %d\n",n,k); 63 for(int i=0;i<k;i++) { 64 if(i>0&&i%10==0) putchar('\n'); 65 if(i%10) putchar(' '); 66 printf("%d", c[i]); 67 } 68 printf("\n"); 69 } 70 return 0; 71 }
方法二源码:
1 /* 2 OJ: POJ 3 ID: 3013216109 4 TASK: 3784.Running Median 5 LANG: C++ 6 NOTE: 堆(优先队列) 7 */ 8 #include <cstdio> 9 #include <queue> 10 #define MAX 10005 11 using namespace std; 12 13 priority_queue<int,vector<int>,less<int> > a; //大顶堆 14 priority_queue<int,vector<int>,greater<int> > b; //小顶堆 15 vector<int> c; 16 17 int main() 18 { 19 int t,n,m,x; 20 scanf("%d",&t); 21 while(t--) { 22 scanf("%d %d",&n,&m); 23 while(!a.empty()) a.pop(); 24 while(!b.empty()) b.pop(); 25 c.clear(); 26 for(int i=0;i<m;i++) { 27 scanf("%d",&x); 28 if(a.empty()) { 29 a.push(x); 30 c.push_back(x); 31 continue; 32 } 33 if(x<=a.top()) 34 a.push(x); 35 else 36 b.push(x); 37 38 while(a.size()>b.size()+1) { 39 b.push(a.top()); 40 a.pop(); 41 } 42 while(a.size()<b.size()) { 43 a.push(b.top()); 44 b.pop(); 45 } 46 47 if(i%2==0&&i!=0) 48 c.push_back(a.top()); 49 } 50 51 printf("%d %d\n",n,(m+1)/2); 52 for(int i=0;i<c.size();i++) { 53 if(i>0&&i%10==0) putchar('\n'); 54 if(i%10) putchar(' '); 55 printf("%d", c[i]); 56 } 57 printf("\n"); 58 } 59 return 0; 60 }