zoukankan      html  css  js  c++  java
  • 随时查找中位数——pat1057

    http://pat.zju.edu.cn/contests/pat-a-practise/1057

    题目的意思是可以在一个可以任意添加于删除整数的集合里随时查找该集合的中位数

    每次查找用nlogn的方法显然会超时

    所以要一种方法接近0(N)的查找方法,  ( 计算第k大的数会超时!!)

    比如当前有1,4,7 

    则树状数组的sum结果会是 1,1,1,2,2,2,3

    现在就变成了二分查找(3+1)/2 ,即2的最左端的位置

    ps: 2分查找有两种形式 (有一种会出错)

    int find(int value)// 1,2,3 
    {
        int mid,ll=1,rr=3;
        while(ll<=rr)
        {    
            mid=(ll+rr)/2;
            if(value<=s[mid])rr=mid-1;
            else ll=mid+1; 
        }
        return ll;
    }

    这种查找1,2,3都不会出错

    int find(int value)//1,2,3
    {
        int mid,ll=1,rr=3;
        while(ll<rr-1)
        {    
            mid=(ll+rr)/2;
            if(value<=s[mid])rr=mid;
            else ll=mid; 
        }
        return rr;
    }

    这种查找1是会出错!!!

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<stack>
    using namespace std;
    
    int n=100000;
    int tree[110009];
    int add[110009];
    int size=0;
    
    int lowbit(int x)
    {
        return x&(-x);
    }
    
    void updata(int x,int c)
    {
        int i;
        for(i=x;i<=n;i+=lowbit(i))
        {
            tree[i]+=c;
        }
    }
    
    int getsum(int x)
    {
        int i;
        int temp=0;
        for(i=x;i>=1;i-=lowbit(i))
        {
            temp+=tree[i];
        }
        return temp;
    }
    
    int find()
    {
        int ll=0,rr=100000,mid=(ll+rr)/2;
    
        int sum;
        while(ll<=rr){
            mid=(ll+rr)/2;
            sum=getsum(mid);
            if(sum< ((size+1)/2)) ll=mid+1;
            else if(sum> ((size+1)/2)) rr=mid-1;
            else if(sum == ((size+1)/2)) rr=mid-1;
        }
        return ll;
    }
    
    int main()
    {
        int t;
        scanf("%d",&t);
        int i,temp;
        char ss[99];
        stack<int>sta;
        for(i=0;i<=n;i++){
            tree[i]=0;
            add[i]=0;
        }
        
        for(i=1;i<=t;i++){
            scanf("%s",ss);
            if(ss[2]=='p'){
                if(size==0){
                    printf("Invalid
    ");
                }else{
                    printf("%d
    ",sta.top());
                    updata(sta.top(),-1);
                    add[sta.top()]--;
                    sta.pop();
                    size--;
                }
            }
            
            if(ss[2]=='s'){
                scanf("%d",&temp);
                add[temp]++;
                sta.push(temp);
                updata(temp,1);
                size++;
            }
            
            if(ss[2]=='e'){
                if(size==0){
                    printf("Invalid
    ");
                }else{
                    printf("%d
    ",find());
                }
            }
        }
        
        return 0;
    }
    View Code
  • 相关阅读:
    Aurora 数据库支持多达五个跨区域只读副本
    Amazon RDS 的 Oracle 只读副本
    Amazon EC2 密钥对
    DynamoDB 读取请求单位和写入请求单位
    使用 EBS 优化的实例或 10 Gb 网络实例
    启动 LAMP 堆栈 Web 应用程序
    AWS 中的错误重试和指数退避 Error Retries and Exponential Backoff in AWS
    使用 Amazon S3 阻止公有访问
    路由表 Router Table
    使用MySQLAdmin工具查看QPS
  • 原文地址:https://www.cnblogs.com/huhuuu/p/3294350.html
Copyright © 2011-2022 走看看