ZOJ 3612 Median multiset或vector+二分

题意:给定n个操作,每个操作有两种:

1)add x 把x添加到数列中,这个数列的结果是递增的,添加过后输出中间值,如果是偶数的话就输出中间两个数之和的平均值。

2)remove x 把x从数列中删掉一个,如果数列是空的或者数列中不存在这个值,输出Wrong!如果存在这个数,删去过后数列为空就输出Empty!否则输出中间值,如果是偶数的话就输出中间两个数之和的平均值。

做法:

可以使用multiset,使用这个的话要维护一个multiset迭代器。

可以使用vector+二分插入,输出时直接输出就行。

注:cout会TLE的。。printf是可以过的。。

详情代码:

代码1:

//First Edit Time:	2014-07-16 22:10
//Last Edit Time:	2014-07-16 22:11
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;
multiset <int> ss;
multiset <int> ::iterator it,mid;
char str[10];
int main()
{
    int t,n,x;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        ss.clear();
        while(n--){
            scanf("%s%d",str,&x);
            if(str[0]=='a'){
                ss.insert(x);
                if(ss.size()==1)mid=ss.begin();
                else if(ss.size()%2==0&&*mid<=x)++mid;
                else if(ss.size()%2==1&&*mid> x)--mid;
            }
            else if(str[0]=='r'){
                it=ss.find(x);
                if(it==ss.end()){
                    printf("Wrong!\n");
                    continue;
                }
                if(it != mid){
                    if(ss.size()%2==0&&*mid<x)--mid;
                    else if(ss.size()%2==1&&*mid>=x)++mid;
                }
                else {
                    if(ss.size()%2==0)--mid;else ++mid;
                }
                ss.erase(it);
                if(ss.empty()){
                    printf("Empty!\n");
                    continue;
                }
            }
            if(ss.size()%2==1){ printf("%d\n",*mid); }
            else {
                it=mid;
                it--;
                long long ans=(long long)*mid+(long long)*it;
                //printf("ans:%lld\n",ans);
                if(ans%2==0)printf("%lld\n",ans/2);
                else printf("%.1lf\n",(double)ans/2.0);
            }
        }
    }
    return 0;
}
代码2:
//First Edit Time:	2014-07-17 00:03
//Last Edit Time:	2014-07-17 00:03
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <algorithm>
using namespace std;
typedef long long LL;
vector <LL> a;
int n;
char str[10];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        a.clear();
        LL x;
        for(int i=0;i<n;i++){
            scanf(" %s%lld",str,&x);
            int pos=lower_bound(a.begin(),a.end(),x)-a.begin();
            if(str[0]=='r'){
                if(pos>=(int)a.size()||a[pos]!=x){ puts("Wrong!");continue; }
                else {
                    a.erase(a.begin()+pos);
                    if(a.size()==0){ puts("Empty!");continue; }
                }
            }
            else if(str[0]=='a'){
                a.insert(a.begin()+pos,x);
            }
            if(a.size()%2==0){
                LL ans=a[a.size()/2]+a[a.size()/2-1];
                if(ans%2==0)printf("%lld\n",ans/2);
                else printf("%.1lf\n",(double)ans/2.0);
            }
            else printf("%lld\n",a[a.size()/2]);
        }
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值