【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 the median (middle value) of the elements received so far.

Input

The first line of input contains a single integer P, (1 ≤ P ≤ 1000), which is the number of data sets that follow. The first line of each data set contains the data set number, followed by a space, followed by an odd decimal integer M, (1 ≤ M ≤ 9999), giving the total number of signed integers to be processed. The remaining line(s) in the dataset consists of the values, 10 per line, separated by a single space. The last line in the dataset may contain less than 10 values.

Output

For each data set the first line of output contains the data set number, a single space and the number of medians output (which should be one-half the number of input values plus one). The output medians will be on the following lines, 10 per line separated by a single space. The last line may have less than 10 elements, but at least 1 element. There should be no blank lines in the output.

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解析:动态维护中位数方法:建立两个二叉堆:一个小根堆,一个大根堆。在依次读入这个整数序列的过程中,设当前序列长度为M,我们始终保持:1、序列中从小到大排名为1~M/2的整数存储在大根堆中:2、序列中从小到大排名为M/2+1~M的整数存储在小根堆中。任何时候,如果某一个堆中的元素过多,打破了这个性质,就取出该堆的堆顶插入另一个堆。这样一来,序列的中位数就是小根堆的堆顶。每次新读入一个数值X后,若X比中位数小,则插入大根堆,否则插入小根堆,在插入之后检查并维护上述性质即可。这就是“对顶堆”算法。(本题对格式要求严格)
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
int T,n,m,a[50005];

priority_queue<int,vector<int>, greater<int> > q;//从小到大输出:小顶堆 

priority_queue<int> p;//从大到小输出 :大顶堆 

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        while(!q.empty())q.pop();
        while(!p.empty())p.pop();
        scanf("%d%d",&m,&n);
        printf("%d %d\n",m,(n+1)/2);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        q.push(a[1]);
        printf("%d",a[1]);
        int cnt=1;
        for(int i=2;i<=n;i++)
        {
            if(a[i]>q.top()) q.push(a[i]);
            else p.push(a[i]);
            if(i%2!=0){
                while(p.size()>(i/2))
                {
                    q.push(p.top());
                    p.pop();
                }
                while(q.size()>(i-(i/2)))
                {
                    p.push(q.top());
                    q.pop();
                }
                cnt++;
                if(cnt%10==1) printf("\n%d",q.top());
                else printf(" %d",q.top());
            }
        }
        puts("");//换行坑人......
    }
}            

原文地址:https://www.cnblogs.com/719666a/p/10163801.html

时间: 2024-10-08 20:45:19

【POJ3784】Running Median的相关文章

【HackerRank】Running Time of Quicksort

题目链接:Running Time of Quicksort Challenge In practice, how much faster is Quicksort (in-place) than Insertion Sort? Compare the running time of the two algorithms by counting how many swaps or shifts each one takes to sort an array, and output the dif

【POJ 3784】 Running Median

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

【Leetcode】4. Median of Two Sorted Arrays

题目描述: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). 解题思路: 这道题个人觉得是很难的,要想解出这个题,就必须了解一下几点: 1.求一列长度为len的数字的中位数,其实也可以被看做是求第len/2

【LeeetCode】4. Median of Two Sorted Arrays

There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)). Example 1: nums1 = [1, 3] nums2 = [2] The median is 2.0 Example 2: nums1 = [1,

【hadoop】 running beyond virtual memory错误原因及解决办法

问题描述: 在hadoop中运行应用,出现了running beyond virtual memory错误.提示如下: Container [pid=28920,containerID=container_1389136889967_0001_01_000121] is running beyond virtual memory limits. Current usage: 1.2 GB of 1 GB physical memory used; 2.2 GB of 2.1 GB virtual

【CF1201C】Maximum Median

题意: 给定一个长度为 $n$ 的序列,并得到了 $k$ 次操作的机会,每一次操作就是把其中一个数的值加 $1$. 求合理安排这 $k$ 次操作,使得结果序列的中位数最大. $1 \le n \le 2*10^5,1 \le k \le 10^9$ 分析: 我们可以用贪心策略想,如果给原始序列小于中位数的数进行操作,那么答案肯定不是最优的,不如给较大的数字. 所以,我们可以删去这个序列中所有小于中位数的数. 删去之后,那原来的中位数就变成了这个序列中最小的数了. 问题便转换成 “最小值最大” 这

【LeetCode】堆 heap(共31题)

[23] Merge k Sorted Lists [215] Kth Largest Element in an Array (无序数组中最小/大的K个数) 给了一个无序数组,可能有重复数字,找到第 k 个最大的元素并且返回这个元素值. 题解:直接用直接用个堆保存数组中最大的 K 个数.时间复杂度是 O(NlogK). 1 //时间复杂度是 O(NlogK), 用堆辅助. 2 class Solution { 3 public: 4 int findKthLargest(vector<int>

【LeetCode】设计题 design(共38题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [146]LRU Cache [155]Min Stack [170]Two Sum III - Data structure design [173]Binary Search Tree Iterator [208]Implement Trie (Prefix Tree) [211]Add and Search Word - Data structure desig

【sql】leetcode习题 (共 42 题)

p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [175]Combine Two Tables [176]Second Highest Salary [177]Nth Highest Salary [178]Rank Scores [180]Consecutive Numbers [181]Employees Earning More Than Their Managers [182]Duplicate Email