題目描述
給出一個長度爲 NNN 的非負整數序列 AiA_iAi ,對於所有 1≤k≤(N+1)/21 ≤ k ≤ (N + 1) / 21≤k≤(N+1)/2 ,輸出 A1,A3,…,A2k−1A_1, A_3, …, A_{2k - 1}A1,A3,…,A2k−1 的中位數。即前 1,3,5,…1,3,5,…1,3,5,… 個數的中位數。
輸入輸出格式
輸入格式:第 111 行爲一個正整數 NNN ,表示了序列長度。
第 222 行包含 NNN 個非負整數 Ai(Ai≤109)A_i (A_i ≤ 10^9)Ai(Ai≤109) 。
輸出格式:共 (N+1)/2(N + 1) / 2(N+1)/2 行,第 iii 行爲 A1,A3,…,A2k−1A_1, A_3, …, A_{2k - 1}A1,A3,…,A2k−1 的中位數。
輸入輸出樣例
說明
對於 20%20\%20% 的數據, N≤100N ≤ 100N≤100 ;
對於 40%40\%40% 的數據, N≤3000N ≤ 3000N≤3000 ;
對於 100%100\%100% 的數據, N≤100000N ≤ 100000N≤100000 。
分析;
思維比較巧妙
1。兩個堆,借鑑,max,min;
2。輸入第一個數字後,每輸入兩個數字要輸出一次,所以用bool標記,初始爲1,從第二個數字開始,每輸入一個改變一次;
a1 | a2 | a3 |
1 | 0 | 1 |
當bool爲真時就意味着要輸出了;
3。堆只能輸出堆頂的數字,所以要把中位數放在堆頂;
min中從小到大排,優先隊列默認從大到小,所以入隊時爲push(-a);則相當於從小到大;
如果比min中最小的大就放到max中去;
如果兩個堆相差2說明較長堆中第二個數是中位數,這時要轉移top數到另一個堆,以便輸入新數據,得到新中位數;
#include<cstdio>
#include<iostream>
#include<queue>
using namespace std;
int main()
{
int n,a;
scanf("%d",&n);
priority_queue<int>max,min;
scanf("%d",&a);printf("%d\n",a);
min.push(-a);
bool no=1;
for(int i=1;i<n;i++)
{
no=1-no;
scanf("%d",&a);
if(a>=-min.top())min.push(-a);else max.push(a);
if(min.size()-max.size()==2){max.push(-min.top()),min.pop();}
else if(max.size()-min.size()==2){min.push(-max.top()),max.pop();}
if(no)
{
if(min.size()>max.size())printf("%d\n",-min.top());
else printf("%d\n",max.top());
}
}
return 0;
}