题意:输入M个数,当已输入的个数为奇数个时输出此时的中位数。
一共有M/2+1个中位数要输出,每一行10个。
思路:用两个优先队列,一个是大顶堆,一个小顶堆,大顶堆中存放比中位数小的数,小顶堆中存放比中位数大的数,把第一个数放入大顶堆,如果当前数比上个中位数小就放入大顶堆,否则就就放入小顶堆。当大顶堆比小顶堆多2个元素或者小顶堆比大顶堆多2个元素的时候,就把多的那个顶堆的堆顶放到另一个堆。要求中位数时,如果是奇数时,就是元素多的堆顶,偶数时是两个堆顶的平均数。
代码:
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int kase;
scanf("%d",&kase);
int n;
scanf("%d",&n);
priority_queue<int>q1;//大顶堆:比中位数小
priority_queue<int, vector<int>, greater<int> >q2;//小顶堆:比中位数大
double ls;int cnt=0;
if(n%2==1)printf("%d %d\n",kase,(n+1)/2);
else printf("%d %d\n",kase,n/2);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
//printf("(%.1f)\n",ls);
if(q1.empty()||1.0*x<ls)q1.push(x);
else q2.push(x);
if(q1.size()-q2.size()==2)
{
//printf("!\n");
int temp=q1.top();
q1.pop();
q2.push(temp);
}
else if(q2.size()-q1.size()==2)
{
//printf("?\n");
int temp=q2.top();
q2.pop();
q1.push(temp);
}
//if(!q1.empty())printf("q1:%d\n",q1.top());
//if(!q2.empty())printf("q2:%d\n",q2.top());
if(i%2==1)
{
if(q1.size()>q2.size())
ls=q1.top(),printf("%d ",q1.top());
else
ls=q2.top(),printf("%d ",q2.top());
cnt++;
if(cnt%10==0)printf("\n");
}
else ls=(q1.top()+q2.top())/2.0;
}
printf("\n");
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!