• Running Median 动态求中位数


    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

    用两个堆, 大顶堆和小顶堆

    每次输入一个数,如果这个数比当前的中位数大,就存入小顶堆中, 否则就存入大顶堆。

    然后调整, 小顶堆元素的个数要等于大顶堆的元素个数,或者比其多1。

    如果小顶堆的元素太多,就塞到大顶堆里,反之亦然

    这样一来就会发现。小顶堆的元素比所有大顶堆的元素都大, 而且小顶堆的堆顶就是中位数。

    /*Running Median 动态求中位数
    这个用到了堆,
    用两个堆, 大顶堆和小顶堆 
    每次输入一个数,如果这个数比当前的中位数大,就存入小顶堆中,  否则就存入大顶堆。
    这两个队列,一个从小到大排序,另一个从大到小 
    */
    #include<iostream> 
    #include<queue>
    #include<vector>
    #include<algorithm>
    using namespace std;
    /*
    priority_queue<int>q;//大根堆
    priority_queue<int,vector<int>,greater<int> >Q;//小根堆
    */
    priority_queue<int,vector<int>,greater<int>> q1;        //从小到大排列
    //q1放的是第一个数(当作中位数处理)和比其大的数 
    priority_queue<int,vector<int>,less<int>> q2;           //从大到小排列
    vector<int> g;
    void add(int x)
    {
    	if(q1.empty())
    	{
    		q1.push(x);
    		return; //保证第一个数可以被记录下来 
    	}
    	if(x>q1.top)
    		q1.push(x);
    	else
    		q2.push(x);
    	while(q1.size()<q2.size())
    	{
    		q1.push(q2.top());
    		q2.pop();
    	}
    	while(q1.size()>q2.size())
    	{
    		q2.push(q1.top());
    		q1.pop();
    	}
    }
    int main()
    {
    	int t,cas,n,x;
    	cin>>t;
    	while(t--)
    	{
    		//开始保证这两个队列为空 
    		while(!q1.empty()) q1.pop();
    		while(!q2.empty()) q2.pop();
    		g.clear();
    		cin>>cas>>n;
    		for(int i=0;i<n;i++)
    		{
    			cin>>x;
    			add(x);
    			if(i%2==0)
    				g.push_back(q1.top());
    		}
    		cout<<cas<<(n+1)/2<<endl;
    		for(int i = 0; i < g.size(); i++) 
    		{
                if(i > 0 && i % 10 == 0) putchar('
    ');
                if(i % 10) putchar(' ');
                cout<<g[i];
            }
    		cout<<endl;
    	}
    	return 0;
    }
    
  • 相关阅读:
    jquery流行的插件收集
    简单遮罩层
    生成任意位数随机验证码
    30个图片浏览插件收集
    [转载]12个jQuery Lightbox效果插件
    jqzoom图片放大镜效果
    23个超流行的jQuery相册插件收集
    在suse上创建UDEV Rules For RAC OCR And Voting Devices
    /etc/fstab文件中的一些参数
    Oracle提供的自治事务记录日志的方法
  • 原文地址:https://www.cnblogs.com/serendipity-my/p/12825468.html
Copyright © 2020-2023  润新知