AcWing 106. 动态中位数

原题链接

考察:堆排序

这里涉及一个新算法:对顶堆.

其实我也第一次学

思路:
       设序列长度为M,用小顶堆维护序列中M/2+1~M个数,用大顶堆维护1~M/2个数,我们动态地维护输入的数字,如果当前数比小顶堆的堆顶小就加入大顶堆,如果大就加入小顶堆.要注意我们必须保证大顶堆的size不能超过M/2,小顶堆的size不能超过M/2+1(这里保证M为奇数)

易错:

      注意输入输出格式

本蒟蒻发现这道题可以全程在线处理,中位数的个数就是(n+1)/2...

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <queue>
 6 using namespace std;
 7 int main() 
 8 {
 9     int T;
10     scanf("%d",&T);
11     while(T--)
12     {
13         int id,n,cnt = 0;
14         priority_queue<int,vector<int>,greater<int> > gr;
15         priority_queue<int,vector<int>,less<int> > le;
16         scanf("%d%d",&id,&n);
17         printf("%d %d\n",id,n+1>>1);
18         for(int i=1;i<=n;i++)
19         {
20             int x; scanf("%d",&x);
21             if(le.empty()) { le.push(x);} 
22             else if(x>le.top()) gr.push(x);
23             else le.push(x);
24             if(le.size()<=gr.size())
25             {
26                 while(le.size()<=gr.size())
27                 {
28                     le.push(gr.top());
29                     gr.pop();
30                 }
31             }
32             if(gr.size()+1<le.size())
33             {
34                 while(gr.size()+1<le.size())
35                 {
36                     gr.push(le.top());
37                     le.pop();
38                 }
39             }
40             if(i%2) cnt++,printf("%d ",le.top());
41             if(i%2&&cnt%10==0) printf("\n");
42         }
43         if(cnt%10!=0) printf("\n");
44     }
45     return 0;
46 }

 

2021.3.5 二刷,做出来了

         要注意的点:

  1. le.size始终是gr.size+1
  2. 注意cnt%10==0时不要输出多余行.

 

posted @ 2021-01-05 22:46  acmloser  阅读(71)  评论(0编辑  收藏  举报