题意:读入一些32位int范围内的整数,当读入奇数个时,输出目前读入的这些值的中位数。
第一行一个整数P,表示测试数据组数。 每组测试数据,第一行一个整数n,表示元素个数。 接下里n个整数,每10个一行,最后一行可能不满10个。
输出中位数时,也需要10个一行,最后一行可能不满10个,但至少会有1个。
思路:
建两个堆, 大顶堆和小顶堆
每次输入一个数,如果这个数比当前的中位数大,就存入小顶堆中, 否则就存入大顶堆。
然后调整, 小顶堆元素的个数要等于大顶堆的元素个数,或者比其多1。
如果小顶堆的元素太多,就塞到大顶堆里,反之亦然
这样一来就会发现。小顶堆的元素比所有大顶堆的元素都大, 而且小顶堆的堆顶就是中位数。
思路借鉴于https://blog.csdn.net/sdj222555/article/details/43058443 写的很好!
#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#include<queue>
#define ll long long
using namespace std;
priority_queue<int,vector<int>,greater<int> > qx;
priority_queue<int,vector<int>,less<int> > qd;
void add(int x)
{
if(qx.empty())
{
qx.push(x);
return;
}
if(x>qx.top())
qx.push(x);
else qd.push(x);
while(qx.size()<qd.size())
{
int temp=qd.top();
qd.pop();
qx.push(temp);
}
while(qx.size()>qd.size()+1)
{
int temp=qx.top();
qx.pop();
qd.push(temp);
}
}
int main()
{
int t,tt,n,i;
cin>>t;
while(t--)
4{
cin>>tt>>n;
int a[10000],ans[10000],cnt=0,temp;
while(!qx.empty())
qx.pop();
while(!qd.empty())
qd.pop();
for(i=1;i<=n;i++)
{
cin>>temp;
add(temp);
if(i%2)
ans[cnt++]=qx.top();
}
cout<<tt<<" "<<cnt<<endl;
for(i=0;i<cnt;i++)
{
cout<<ans[i]<<" ";
if((i+1)%10==0)
cout<<endl;
}
if(cnt%10)
cout<<endl;
}
return 0;
}