POJ 3784 - Running Median(动态中位数) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:http://poj.org/problem?id=3784

题目大意:

依次给出n个数字,求在数据输入过程中的所有中位数。(共有(n+1)/2个)

输入格式:

输入一个数字P(1<=P<=1000),表示数据组数。

对于每组数据,第一行输入数据组号和数字总个数(1<=个数<=9999),中间以一个空格隔开。

接下来每行给出至多10个数字。

输出格式:

对于每组数据,第一行输出数据组号和中位数个数,中间以一个空格隔开。

接下来每行输出至多10个数字,表示即时中位数。

Sample Input

3
1 9
1 2 3 4 5 6 7 8 9
2 9
9 8 7 6 5 4 3 2 1
3 23
23 41 13 22 -3 24 -31 -11 -8 -7
3 5 103 211 -311 -45 -67 -73 -81 -99
-33 24 56

Sample Output

1 5
1 2 3 4 5
2 5
9 8 7 6 5
3 12
23 23 22 22 13 3 5 5 3 -3
-7 -3

分析:

对顶堆,即用两个堆,一个大根堆一个小根堆。每次比较两个堆的堆顶,如果不相等就交换堆顶,否则堆顶即为所要求的中位数。

证明不再给出,想想应该都明白。

AC代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<queue>
 6
 7 inline void read(int &x)
 8 {
 9     char ch = getchar(),c = ch;x = 0;
10     while(ch < ‘0‘ || ch > ‘9‘) c = ch,ch = getchar();
11     while(ch >= ‘0‘ && ch <= ‘9‘) x = (x<<1)+(x<<3)+ch-‘0‘,ch = getchar();
12     if(c == ‘-‘) x = -x;
13 }
14
15 std::priority_queue <int> lq,sq;
16 //lq为大根堆,sq为小根堆
17
18 inline void init()
19 {
20     while(!lq.empty())
21         lq.pop();
22     while(!sq.empty())
23         sq.pop();
24 }
25
26 int main()
27 {
28 //    freopen("1.txt","r",stdin);
29     int n,t,x,a,b,cnt;
30     read(t);
31     while(t --)
32     {
33         read(cnt);
34         read(n);
35         init();
36         printf("%d %d\n",cnt,(n+1)/2);
37         for(int i = 1;i <= n;++ i)
38         {
39             read(x);
40             lq.push(x),sq.push(-x);
41             if(i%2 == 0) continue;
42             while(lq.top() != -sq.top())
43             {
44                 a = lq.top(),lq.pop();
45                 b = -sq.top(),sq.pop();
46                 sq.push(-a),lq.push(b);
47             }
48             printf("%d ",lq.top());
49             if(((i+1)/2)%10 == 0) puts("");
50             else if((n%2 == 1 && i == n) || (n%2 == 0 && i == n-1)) puts("");
51         }
52     }
53     return 0;
54 }
时间: 2024-10-10 10:15:12

POJ 3784 - Running Median(动态中位数) 题解的相关文章

POJ 3784 Running Median (动态中位数)

题目链接:http://poj.org/problem?id=3784 题目大意:依次输入n个数,每当输入奇数个数的时候,求出当前序列的中位数(排好序的中位数). 此题可用各种方法求解. 排序二叉树方法,每个结点保存以其为根的左右子树中数的个数.如果数据出的够严格,这种方法会被卡的,除非是通过动态调整维持树的高度较小. 排序二叉树的代码如下: #include <cstdio> using namespace std; #define N 20000 struct Node { int v;

POJ 3784 Running Median 动态求中位数 堆

题意. 1000个case 每个case 输入若干个数,对第k个输入,如果k为奇数,则输出前k个数的中位数 那么这就是动态求中位数了 实现的思路也比较简洁 用两个堆, 大顶堆和小顶堆 每次输入一个数,如果这个数比当前的中位数大,就存入小顶堆中,  否则就存入大顶堆. 然后调整, 小顶堆元素的个数要等于大顶堆的元素个数,或者比其多1. 如果小顶堆的元素太多,就塞到大顶堆里,反之亦然 这样一来就会发现.小顶堆的元素比所有大顶堆的元素都大, 而且小顶堆的堆顶就是中位数. 那么怎么样才能想到这样一个思路

HDU 3282 Running Median 动态中位数,可惜数据范围太小

Running Median Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3282 Description For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read

POJ 3784 Running Median(动态维护中位数)

Description For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of the elements received so far. Input The first line of input contains

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 输入的数为奇数个时.

POJ 3784 Running Median

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1670   Accepted: 823 Description For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (midd

poj 3784 用堆动态求解中位数

堆真是一种简单而又神奇的数据结构,以前用它求过前kth的数,现在又可以用两个堆来动态求解中位数. 算法: 构建一个大顶堆和一个小顶堆,分别记为g和l. 假设当前中位数为mid,新读入一个数为tmp,则: 1.如果tmp < mid,则将tmp插入大顶堆,跳到步骤3. 2.如果tmp >= mid,则将tmp插入小顶堆,跳到步骤4. 3.如果大顶堆的元素个数比小顶堆多2(两个堆个数不平衡),则将mid插入小顶堆,弹出大顶堆堆顶元素为新的mid. 4.与步骤3相反,如果小顶堆的元素个数比大顶堆多2

hdu 3282 Running Median

题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3282 Running Median Description For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output the median (middle value) of th

【POJ3784】Running Median

Running Median Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3406   Accepted: 1576 Description For this problem, you will write a program that reads in a sequence of 32-bit signed integers. After each odd-indexed value is read, output