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 }

时间: 2024-08-01 10:31:53

POJ 3784 Running Median (最大最小堆)的相关文章

POJ 3784 Running Median 动态求中位数 堆

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

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

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=3784 题目大意: 依次给出n个数字,求在数据输入过程中的所有中位数.(共有(n+1)/2个) 输入格式: 输入一个数字P(1<=P<=1000),表示数据组数. 对于每组数据,第一行输入数据组号和数字总个数(1<=个数<=9999),中间以一个空格隔开. 接下来每行给出至多10个数字. 输出格式: 对于每组数据,第一行输出数据组号和中位数个数,中间

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(动态维护中位数)

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

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】 Running Median

[题目链接] http://poj.org/problem?id=3784 [算法] 对顶堆算法 要求动态维护中位数,我们可以将1-M/2(向下取整)小的数放在大根堆中,M/2+1-M小的数放在小根堆中 每次插入元素时,先将插入元素与小根堆堆顶比较,如果比堆顶小,则插入小根堆,否则,插入大根堆,然后,判断两个堆 的元素个数是否平衡,若不平衡,则交换两个堆的堆顶 [代码] #include <algorithm> #include <bitset> #include <ccty

Google 面试题:Java实现用最大堆和最小堆查找中位数 Find median with min heap and max heap in Java

Google面试题 股市上一个股票的价格从开市开始是不停的变化的,需要开发一个系统,给定一个股票,它能实时显示从开市到当前时间的这个股票的价格的中位数(中值). SOLUTION 1: 1.维持两个heap,一个是最小堆,一个是最大堆. 2.一直使maxHeap的size大于minHeap. 3. 当两边size相同时,比较新插入的value,如果它大于minHeap的最大值,把它插入到minHeap.并且把minHeap的最小值移动到maxHeap. ...具体看代码 1 /*********

poj 3784(对顶堆)

Running Median Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1824   Accepted: 889 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 t

最小堆的维护,POJ(2051)

题目链接:http://poj.org/problem?id=2051 ///维持最小堆(优先队列)POJ2051 #include <iostream> #include <string> using namespace std; struct Node { int Now; ///出堆的时间 int id; int p; ///时间间隔 }; Node node [3001]; int K; ///输出个数 void down (Node H[],int s,int m) {