建立一个大根堆与小根堆,大根堆中存(n+1)/2 的元素,中位数即为大根堆堆顶
用一个从大到小排序的优先队列q1来模拟小于x的数。
从小到大排序的优先队列q2来模拟大于x的数。
动态维护两个优先队列的元素个数。q1.size()=q2.size() 输入的数为偶数个时,
q1.size()=q2.size()+1 输入的数为奇数个时。
每次要输出的中位数恰好是q1.top().
#include<cstdio> #include<queue> #include<algorithm> #include<cstring> #include<vector> using namespace std; const int maxn=10000; priority_queue<int>q1; priority_queue<int,vector<int>,greater<int> >q2; int a[maxn]; int main(){ int t; int cas,n,top; int p; scanf("%d",&t); while(t--){ while(!q1.empty()) q1.pop(); while(!q2.empty()) q2.pop(); memset(a,0,sizeof(a)); top=0; scanf("%d%d",&cas,&n); for (int i=1;i<=n;i++){ scanf("%d",&p); if(q1.empty()) q1.push(p); else if(p>q1.top()) q2.push(p); else q1.push(p); while(q1.size()<q2.size()){ int t=q2.top(); q2.pop(); q1.push(t); } while(q1.size()-1>q2.size()){ int t=q1.top(); q1.pop(); q2.push(t); } if((i>>0)&1) a[++top]=q1.top(); } printf("%d %d ",cas,top); for (int i=1;i<=top;i++){ printf("%d",a[i]); if(i%10&&i!=top) printf(" "); if(i%10==0) printf(" "); } if(top%10) printf(" "); } return 0; }