洛谷 中位数
优先队列的使用
输入样例
7 1 3 5 7 9 11 6
输出
1 3 5 6
题目意思解释:
输入7,表示有七个数,七个数分别是1 3 5 7 9 11 6;
求前1个数的中位数,只有1这一个数,所以输出1;
求前三个数的中位数,有1 3 5,中位数是3,输出3;
求前五个数的中位数,有1 3 5 7 9,中位数是5,输出5;
求前七个数的中位数,按顺序来有1 3 5 6 7 9,中位数是6,输出6;
…由于只有七个数,结束输出,输入的数并不是有序的哦
思路解析:
用两个堆,一个mid变量来存中位数,mid左边是大根堆,右边是小根堆,(此题中,中位数不存在求和再/2的情况)
初始先让mid=第一个输入的数字,然后输出;这一步应该看得懂的
然后输入3,与我们的中位数来比较一下,如果比mid大,就放到小根堆里面去,反之放到大根堆里面去,3是第二个数,不用输出:
然后输入5,根据上一步,放到小根堆里面去,此时是输入的第三个数了,需要输出了,我们来平衡一下两个堆:
此时最大堆中只有1,mid=3,最小堆中只有5,输出mid,3
然后输入7,发现比3大,就放到最小堆里面去;第四个数不用输出;
然后输入9,同理,要输出了,就要开始平衡堆了:
变成这样:输出mid5;
后面的步骤就是跟上面说的一样了;
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
priority_queue<int> b;
priority_queue<int, vector<int>, greater<int> > s;
int n, num, mid;
int main()
{
cin >> n;
int num;
cin >> num;
//输出第一个
mid = num;
cout << mid << endl;
for ( int i = 2; i <= n; ++i ) {
cin >> num;
//比当前mid大,就往小根堆里面push
if ( num > mid ) s.push(num);
//比当前mid小,放大根堆去
else b.push(num);
//奇数就输出
if ( i % 2 ) {
//平衡堆,就是先把mid放进size小的里面,在把mid更新为开始size大的堆的top(),
//然后size大的pop();
while ( b.size() != s.size() ) {
if ( s.size() > b.size() ) {
b.push(mid);
mid = s.top();
s.pop();
}
else {
s.push(mid);
mid = b.top();
b.pop();
}
}
cout << mid << endl;
}
}
return 0;
}