要求编写一个容器,它可支持两种操作: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;
- }