要求編寫一個容器,它可支援兩種操作:push()和pop(),push(K)操作可將元素K放入容器,pop()操作可將容器中的中位值彈出。
例如:push(1),push(2),push(3)後pop()[輸出為2]。
解決方案,建立一個最大值優先的優先隊列,將其記為左隊列ql,建立一個最小值優先的優先隊列,將其記為右隊列qr,
我們規定ql不為空白時,ql.top()為中位值,記為mid,對於push(k),如果k>mid,則將k壓入右邊優先隊列qr,如果k<=mid怎將其壓入
左邊優先隊列ql,然後將左右兩個隊列做平衡處理。pop()則只需將ql.top()的值彈出後做平衡處理即可。這種方法和快排演算法中將
一個序列分成大於mid的和小於等於mid的兩部分的做法相似。
題目連結:http://acm.hdu.edu.cn/diy/contest_showproblem.php?cid=16719&pid=1005
代碼:
#include<cstdio>#include<vector>#include<queue>using namespace std;struct cmp1 { bool operator ()(int &a,int &b) { return a>b;//最小值優先 } }; struct cmp2 { bool operator ()(int &a,int &b) { return a<b;//最大值優先 } }; priority_queue<int,vector<int>,cmp1>qr;//最小值優先 priority_queue<int,vector<int>,cmp2>ql;//最大值優先int ls,rs;void balance(void){ int idx=(ls+rs+1)/2; while(ls<idx) { int k=qr.top(); ql.push(k); qr.pop(); ls++; rs--; } while(ls>idx) { int k=ql.top(); qr.push(k); ql.pop(); ls--; rs++; } }void push(int k){ if(ls==0) { ql.push(k); ls++; return ; } int mid=ql.top(); if(k>mid) qr.push(k),rs++; else ql.push(k),ls++; balance();}void pop(void){ if(ls<=0) { printf("No Element!\n"); return ; } int ans=ql.top(); ql.pop(); ls--; balance(); printf("%d\n",ans);}int main(){ int n; while(scanf("%d", &n)!=EOF){ ls=rs=0; qr=priority_queue<int,vector<int>,cmp1>(); ql=priority_queue<int,vector<int>,cmp2>(); for(int i=0;i<n;i++) { int c,k; scanf("%d",&c); if(c==0) { scanf("%d",&k); //printf("push %d\n",k); push(k); } else pop(); //printf("ls=%d rs=%d\n",ls,rs); } printf("\n"); } return 0;}