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 }

 

posted @ 2015-07-16 10:43  ACMan  阅读(600)  评论(0编辑  收藏  举报