zoukankan      html  css  js  c++  java
  • [洛谷P1168]中位数

    题目大意:给你n个数,问你前1、3、5...个数的中位数是多少。

    解题思路:首先,前一个数的中位数一定是第一个数。

    之后,每次都会读进两个数。

    我们需要做到,如果两个数都小于原来的中位数,那么现在的中位数变成比它小的最大的数。

    反之,如果两个数都大于等于原来的中位数,则变成比它大的最小的数。

    如果一个小,一个大于等于,则显然中位数不变。

    可以想到用一个大根堆保存“比当前中位数小的数”,用一个小根堆保存“大于等于当前中位数的数”,

    然后,对于读进来的两个数,把比当前中位数小的放进大根堆里,大于等于当前中位数的放进小根堆里。

    如果两个数都小于当前中位数,则把当前中位数放进小根堆里(因为答案变小了),然后当前中位数变为大根堆顶,大根堆顶弹出。

    反之则把当前中位数放进大根堆里(因为答案变大了),然后当前中位数变为小根堆顶,小根堆顶弹出。

    如果一个大一个小于等于,则中位数不变。

    时间复杂度$O(nlog_2 n)$。

    C++ Code:

    #include<cstdio>
    #include<queue>
    #include<cctype>
    std::priority_queue<int,std::vector<int>,std::greater<int> >small;
    std::priority_queue<int>big;
    int now,n;
    inline int readint(){
    	char c=getchar();
    	for(;!isdigit(c);c=getchar());
    	int d=0;
    	for(;isdigit(c);c=getchar())
    	d=(d<<3)+(d<<1)+(c^'0');
    	return d;
    }
    int main(){
    	n=readint();
    	printf("%d
    ",now=readint());
    	for(int i=(n-1)>>1;i;--i){
    		int a=readint(),p=0;
    		if(a<now)--p,big.push(a);else ++p,small.push(a);
    		a=readint();
    		if(a<now)--p,big.push(a);else ++p,small.push(a);
    		if(p<0){
    			small.push(now);
    			now=big.top();
    			big.pop();
    		}else
    		if(p>0){
    			big.push(now);
    			now=small.top();
    			small.pop();
    		}
    		printf("%d
    ",now);
    	}
    	return 0;
    }
    
  • 相关阅读:
    html5 audio的语法以及属性和方法
    转自可可英语的文章,以激励我努力学习英语。
    Linux下怎么删除非空目录
    Unity脚本时间执行顺序
    一个高手很多同时又能学习英语的问答网站
    Unity中Time.deltaTime的含义及其应用
    用C++画心(转)
    web中将body占满整个页面的办法
    基于FPGA的LCD+CMOS视频采集显示使用小结
    基于iCamera测试500w摄像头-mt9p001,mt9p031,mt9p001模块小结
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/8017837.html
Copyright © 2011-2022 走看看