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 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章