zoukankan      html  css  js  c++  java
  • 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 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

    题目意思:对于n个数,每输入到奇数个数,便求一次中位数。

    解题思路:我开始就直接暴力,到了奇数位,sort一下,找出中位数,这样在UVAlive上没有超时,但在poj上是超时的,看了看网上的代码才知道处理这样一个动态的中位数使用堆来维护,而这个堆使用优先队列来模拟,一周内第二次见到优先队列了。维护一个大根堆和一个小根堆,且保证大根堆里的所有数都比小根堆里的所有数小,而且大根堆的大小等于小根堆或者大1,则大根堆堆顶就是中位数。对于新插入的数,与中位数比较决定插入哪个堆中,插入之后维护一下两个堆的大小。每次维护需要进行常数个堆上的操作,所以复杂度O(nlogn)。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 using namespace std;
     5 priority_queue<int,vector<int>,greater<int> > bh;///从小到大
     6 priority_queue<int,vector<int>,less<int> > sh;///从大到小
     7 int main()
     8 {
     9     int t,n,num;
    10     int i,j,m,p,q,x,y,z,K;
    11     scanf("%d",&t);
    12     while (t--)
    13     {
    14         scanf("%d%d",&num,&n);
    15         printf("%d %d
    ",num,n/2+1);
    16         while (!bh.empty())
    17         {
    18             bh.pop();
    19         }
    20         while (!sh.empty())
    21         {
    22             sh.pop();
    23         }
    24         for (i=1; i<=n; i++)
    25         {
    26             scanf("%d",&x);
    27             if (sh.empty()||sh.top()>x)
    28             {
    29                 sh.push(x);///放入小堆
    30             }
    31             else
    32             {
    33                 bh.push(x);///放入大堆
    34             }
    35             if (sh.size()>(i+1)/2)
    36             {
    37                 x=sh.top();
    38                 sh.pop();
    39                 bh.push(x);
    40             }
    41             if (sh.size()<(i+1)/2)
    42             {
    43                 x=bh.top();
    44                 bh.pop();
    45                 sh.push(x);
    46             }
    47             if (i%2)
    48             {
    49                 printf("%d",sh.top());
    50                 if (i==n||(i+1)%20==0)
    51                 {
    52                     printf("
    ");
    53                 }
    54                 else
    55                 {
    56                     printf(" ");
    57                 }
    58             }
    59         }
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    PDB文件详解
    C++模板常用功能讲解
    Windows下多线程编程(二)
    关于静态库中使用全局变量可能导致的问题
    js中的函数
    js中字符串的加密base64
    列表推导式
    函数和方法的区别
    xshell连不上虚拟机
    网络编程,并行,并发和协程
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/9786958.html
Copyright © 2011-2022 走看看