题意 :依次读入一个整数序列,当读到奇数时,输出此时数列的中位数。
分析 :暴力是不可能暴力的了, 可以建立两个二叉堆,一个大根堆,一个小根堆,大小顺序在前面一半(1 ~ N/2)的序列排在大根堆,排在后面一半(N/2+1 ~ N)的序列排在小根堆,序列为奇数时将中位数放在大根堆堆顶。
当目前序列为奇数时 :读入下一个数字时判断是否大于大根堆的堆顶,如果大于堆顶就插入到小根堆,如果小于堆顶就插入到大根堆,再将大根堆的堆顶插入到小根堆内。
当目前序列为偶数时 :读入下一个数时判断是否大于小根堆的堆顶,如果大于小根堆堆顶,则插入小根堆内,再将小根堆堆顶插入大根堆内,如果小于堆顶
则直接插入大根堆内,大根堆堆顶就是中位数。
小根堆 :priority_queue<int,vector<int>,greater<int> >maxn
大根堆 :priority_queue<int,vector<int>,less<int> >minn
哭辽qaq,代码里面的清除队列的方法不知道为啥用不了,卡了我好久!!!
网上的方法
具体代码
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
/*
void clean_queue_min(priority_queue<int,vector<int>,greater<int> >&a){
priority_queue<int,vector<int>,greater<int> >empty;
swap(a,empty);
}
void clean_queue_max(priority_queue<int,vector<int>,less<int> >&a){
priority_queue<int,vector<int>,less<int> >empty;
swap(a,empty);
}
void clean_queue(queue<int>&a){
queue<int>empty;
swap(empty,a);
}
*/
int main()
{
int n,m,t;
priority_queue<int,vector<int>,greater<int> >minn;//С
priority_queue<int,vector<int>,less<int> >maxn;//´ó
queue<int>ans;
cin>>n;
for(int i=1;i<=n;i++){
cin>>m>>t;
cout<<m<<" "<<(t+1)/2<<endl;
int v;
cin>>v;
maxn.push(v);
ans.push(v);
for(int i=2;i<=t;i++){
cin>>v;
if(i%2==1) {
if(v<minn.top()) maxn.push(v);
else{
minn.push(v);
maxn.push(minn.top());
minn.pop();
}
ans.push(maxn.top());
}
if((i%2==0)){
if(v>maxn.top()) minn.push(v);
else{
maxn.push(v);
minn.push(maxn.top());
maxn.pop();
}
}
}
for(int i=1;ans.size()!=0;i++){
cout<<ans.front();
ans.pop();
if(i%10==0) cout<<endl;
else cout<<" ";
}
while(!maxn.empty()) maxn.pop();
while(!minn.empty()) minn.pop();
while(!ans.empty()) ans.pop();
cout<<endl;
}
return 0;
}