洛谷 P1168 中位数(优先队列)

嗯...

 

题目链接:https://www.luogu.org/problem/P1168

 

这道题暴力是肯定不行的,所以说要用优先队列来维护...

 

思路:

定义一个大根堆,一个小根堆,首先将第一个数随便放进一个堆(这里我们把它放入小根堆),然后再看下一个数,如果这个数比小根堆的堆顶大,那么就把它放入小根堆,否则将它放入大根堆。注意大小根堆的元素个数不能超过2(即不能>1),如果超过,则将元素多的那个堆的堆顶元素压入另一个堆,这样我们就维护了一个类似单调递增的序列,而这道题又比较水,只讨论了奇数个元素的情况,所以最终的答案就是元素较多的堆的堆顶。(下面附一张图,但我感觉不是很好,其实就是一个单调递增的序列...

细节:

第28行到第38行不能写成:

  if(q1.size() - q2.size() > 1){ q2.push(q1.top()) ; q1.pop(); }

 if(q2.size() - q1.size() > 1){ q1.push(q2.top()); q2.pop(); }  

这样的话在pop的之后改变了size的大小...在执行下一条语句还可能合法,然后会....

 

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 #include<cmath>
 5 
 6 using namespace std;
 7 
 8 priority_queue <int> q1;
 9 priority_queue<int, vector<int>, greater<int> > q2;
10 int n, a;
11 
12 int main(){
13     scanf("%d", &n);
14     for(int i = 1; i <= n; i++){
15         scanf("%d", &a);
16         if(i == 1){
17             printf("%d\n", a);
18             q2.push(a);
19             continue;
20         }
21         else{
22             if(a < q2.top()) q1.push(a);
23             else if(a > q2.top()) q2.push(a); 
24             else{
25                 if(q1.size() < q2.size()) q1.push(a);
26                 else q2.push(a);
27             }
28             if(q1.size() - q2.size() > 1 || q2.size() - q1.size() > 1){
29                 if(q1.size() > q2.size()){
30                     q2.push(q1.top()) ;
31                     q1.pop();
32                 }
33                 else{
34                     q1.push(q2.top());
35                     q2.pop();
36                 }
37             }
38         }
39         if(i % 2 && q2.size() > q1.size()) printf("%d\n", q2.top());
40         else if(i % 2 && q1.size() > q2.size()) printf("%d\n", q1.top());
41     }
42     return 0;
43 }
AC代码

 

转载于:https://www.cnblogs.com/New-ljx/p/11285004.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值