[luogu]P1168 中位数[堆]

[luogu]P1168

中位数

题目描述

给出一个长度为N的非负整数序列A[i],对于所有1 ≤ k ≤ (N + 1) / 2,输出A[1], A[3], …, A[2k - 1]的中位数。即前1,3,5,……个数的中位数。

输入输出格式

输入格式:

输入文件median.in的第1行为一个正整数N,表示了序列长度。

第2行包含N个非负整数A[i] (A[i] ≤ 10^9)。

输出格式:

输出文件median.out包含(N + 1) / 2行,第i行为A[1], A[3], …, A[2i – 1]的中位数。

输入输出样例

输入样例1#:

7
1 3 5 7 9 11 6

输出样例1#:

1
3
5
6

【数据范围】

对于20%的数据,N ≤ 100;

对于40%的数据,N ≤ 3000;

对于100%的数据,N ≤ 100000。


好尴尬,一开始理解错题意,把序列排序就输出来了,感觉好傻...

维护两个堆,一个大根堆,一个小根堆,小根堆的最小元素比大根堆的最大元素大,每加进一个元素,如果比大根堆的最大元素小,加到前面的大根堆,否则加到后面的小根堆。

调整大根堆的大小使其为(i+1)/2。

c++的话用STL非常方便。

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5 using namespace std;
 6 inline int read();
 7 const int maxn = 1e5 + 7 ;
 8 priority_queue< int > a;
 9 priority_queue< int > b;
10 int n;
11 namespace lys{
12     int main(){
13         int i,x,y;
14         n=read();    
15         for(i=1;i<=n;i++){
16             x=read();
17             if(a.empty()) a.push(x);
18             else{
19                 if(x<=a.top()) a.push(x);
20                 else b.push(-x);
21             }
22             if(a.size()<((i+1)>>1)){
23                 x=b.top();
24                 b.pop();
25                 a.push(-x);
26             }
27             else if(a.size()>((i+1)>>1)){
28                 x=-a.top();
29                 a.pop();
30                 b.push(x);
31             }
32             if(i&1){
33                 x=a.top();
34                 printf("%d\n",x);
35             }
36         }
37         return 0;
38     }
39 }
40 int main(){
41     lys::main();
42     return 0;
43 }
44 inline int read(){
45     int k=0,f=1;
46     char c=getchar();
47     while(c<'0'||c>'9'){
48         if(c=='-')
49             f=-1;
50         c=getchar();
51     }
52     while(c>='0'&&c<='9'){
53         k=k*10+c-'0';
54         c=getchar();
55     }
56     return k*f;
57 }

 

posted @ 2017-10-31 15:14  iNx  阅读(150)  评论(0编辑  收藏  举报