题目描述
有一个源源不断的吐出整数的数据流,假设你有足够的空间来保存吐出的数。请设计一个名叫MedianHolder的结构,MedianHolder可以随时取得之前吐出所有数的中位数。
[要求]
- 如果MedianHolder已经保存了吐出的N个数,那么将一个新数加入到MedianHolder的过程,其时间复杂度是O(logN)。
- 取得已经吐出的N个数整体的中位数的过程,时间复杂度为O(1)
输入描述:
第一行一个整数Q,表示有Q次询问。
接下来Q行,每行有一个整数opt表示操作类型
若opt=1,则接下来有一个整数N表示将N加入到结构中。
若opt=2,则表示询问当前所有数的中位数
输出描述:
输出若干行,每行一个浮点数数表示该次询问的答案(保留至小数点后一位)
若询问时数据流中没有数输出-1(不需要输出小数点后的数字)
具体输出要求请看样例
示例1
输入
复制
8
1 5
2
1 3
2
1 6
2
1 7
2
输出
复制
5.0
4.0
5.0
5.5
说明
第一次查询时结构内的数为:5
第二次查询时结构内的数为:3 5
第二次查询时结构内的数为:3 5 6
第二次查询时结构内的数为:3 5 6 7
示例2
输入
复制
3
2
1 1
2
输出
复制
-1
1.0
注意:在STL中使用v.size()-v1.size()如果结果为负数,那么会得到一个很大的正数。
#include<iostream>
#include<queue>
using namespace std;
priority_queue<int> big_q;//堆顶元素更大 ,这里储存较小元素
priority_queue<int,vector<int>,greater<int> > small_q;//堆顶元素更小
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
int x;
scanf("%d",&x);
if(x==1)
{
int y;
scanf("%d",&y);
if( big_q.empty() || y<big_q.top() )
big_q.push(y);
else
small_q.push(y);
//调整大,小根堆的元素个数 ,使其相差<1
int len1=big_q.size(),len2=small_q.size();
if(len1 - len2 >1 )
{
int x=big_q.top();
big_q.pop();
small_q.push(x);
}
else if( len2-len1 >1 )// 并且stl模板库中的size()函数相减如果时一个负数那么得到的都是一个很大的整数 v1.size()-v2.size();
{
int x=small_q.top();
small_q.pop();
big_q.push(x);
}
}
else //查询当前的中位数
{
if( big_q.empty() )
cout<<-1<<endl;
else if( big_q.size()==small_q.size() )
{
printf("%.1f\n", 0.5*(big_q.top()+small_q.top() ) );
}
else
{
printf("%.1f\n", big_q.size()>small_q.size() ? 1.0*big_q.top() : 1.0*small_q.top() );
}
}
}
return 0;
}