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 二刷,做出来了
要注意的点:
- le.size始终是gr.size+1
- 注意cnt%10==0时不要输出多余行.