• TZOJ 2943 Running Median(动态中位数)


    描述

    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.

    输入

    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.

    输出

    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.

    样例输入

    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

    样例输出

    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个数输出每输入奇数个时的中位数。

    题解

    动态中位数经典题。

    由于输出奇数个数,相当于中位数只有1个。不会有除2的情况。

    维护两个优先队列,1个从大到小pq1,1个从小到大pq2。

    需要做到,pq1.top就是中位数,那么相当于pq1的个数等于pq2的个数或者多1个,并且pq1中的数<=pq2中的数。

    那么显然对于一个数x,如果目前的中位数pq1.top>x,放到pq1,否则放到pq2。

    放到pq1后,会出现pq1的大小比pq2大2,相当于pq1.top不是中位数了,中位数是pq1.pop后的pq1.top,当然pq1.pop后要把数放到pq2中。

    放到pq2后,会出现pq2的大小比pq1大,相当于中位数在pq2.top,由于维护的是pq2的个数要小于pq1,那么pq2.pop后放到pq1中,pq1.top还是中位数。

    <扩展 如果偶数也要输出怎么办?>

    <显然就是经过维护后的(pq1.top+pq2.top)/2>

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int t,x,ca,n;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&ca,&n);
            printf("%d %d
    ",ca,n/2+1);
            priority_queue< int,vector<int>,less<int> > pq1;
            priority_queue< int,vector<int>,greater<int> >pq2;
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&x);
                if(pq1.empty()||pq1.top()>x)pq1.push(x);
                else pq2.push(x);
                if(pq1.size()>pq2.size()+1)
                {
                    pq2.push(pq1.top());
                    pq1.pop();
                }
                else if(pq1.size()<pq2.size())
                {
                    pq1.push(pq2.top());
                    pq2.pop();
                }
                if(i&1)
                    printf("%d%c",pq1.top(),i==n?'
    ':((i+1)%20?' ':'
    '));
            }
        }
        return 0;
    }
  • 相关阅读:
    一只简单的网络爬虫(基于linux C/C++)————Url处理以及使用libevent进行DNS解析
    一只简单的网络爬虫(基于linux C/C++)————浅谈并发(IO复用)模型
    一只简单的网络爬虫(基于linux C/C++)————支持动态模块加载
    一只简单的网络爬虫(基于linux C/C++)————守护进程
    培训班出身的程序员怎么了
    【技术人成长】知识铺
    几篇QEMU/KVM代码分析文章
    用callgraph生成的两张函数调用关系图
    Qemu对x86静态内存布局的模拟
    KVM技术
  • 原文地址:https://www.cnblogs.com/taozi1115402474/p/12310239.html
Copyright © 2020-2023  润新知