• bzoj1941 Hide and Seek


    Description

    小猪iPig在PKU刚上完了无聊的猪性代数课,天资聪慧的iPig被这门对他来说无比简单的课弄得非常寂寞,为了消除寂寞感,他决定和他的好朋友giPi(鸡皮)玩一个更加寂寞的游戏---捉迷藏。 但是,他们觉得,玩普通的捉迷藏没什么意思,还是不够寂寞,于是,他们决定玩寂寞无比的螃蟹版捉迷藏,顾名思义,就是说他们在玩游戏的时候只能沿水平或垂直方向走。一番寂寞的剪刀石头布后,他们决定iPig去捉giPi。由于他们都很熟悉PKU的地形了,所以giPi只会躲在PKU内n个隐秘地点,显然iPig也只会在那n个地点内找giPi。游戏一开始,他们选定一个地点,iPig保持不动,然后giPi用30秒的时间逃离现场(显然,giPi不会呆在原地)。然后iPig会随机地去找giPi,直到找到为止。由于iPig很懒,所以他到总是走最短的路径,而且,他选择起始点不是随便选的,他想找一个地点,使得该地点到最远的地点和最近的地点的距离差最小。iPig现在想知道这个距离差最小是多少。 由于iPig现在手上没有电脑,所以不能编程解决这个如此简单的问题,所以他马上打了个电话,要求你帮他解决这个问题。iPig告诉了你PKU的n个隐秘地点的坐标,请你编程求出iPig的问题。

    Input

    第一行输入一个整数N 第2~N+1行,每行两个整数X,Y,表示第i个地点的坐标

    Output

    一个整数,为距离差的最小值。

    建立k-d树,枚举每个点查询最近点和最远点的曼哈顿距离。

    单次查询最坏时间复杂度O(n0.5)但通常不会达到。

    #include<cstdio>
    #include<algorithm>
    #define inf 2147483647
    inline int abs(int x){return x>0?x:-x;}
    inline int max(int x,int y){return x>y?x:y;}
    inline int min(int x,int y){return x<y?x:y;}
    inline void maxs(int&x,int y){if(x<y)x=y;}
    inline void mins(int&x,int y){if(x>y)x=y;}
    inline int max0(int x){return x>0?x:0;}
    struct pos{
        int x,y;
    };
    struct node{
        int x1,y1,x2,y2;
        int xm,ym;
        int l,r;
        node():x1(inf),y1(inf),x2(-inf),y2(-inf){}
        inline void set(int x,int y){
            x1=x2=xm=x;
            y1=y2=ym=y;
        }
    };
    int dx=0;
    bool operator<(pos a,pos b){
        if(dx)return a.x<b.x;
        return a.y<b.y;
    }
    node ns[500005];
    pos ps[500005];
    int np=1,n;
    int X,Y,minv,maxv,ans(inf);
    int build(int l,int r,int d=0){
        if(l==r)return 0;
        dx=d;
        int m=l+r>>1;
        node&w=ns[np++];
        std::nth_element(ps+l,ps+m,ps+r);
        w.set(ps[m].x,ps[m].y);
        d^=1;
        w.l=build(l,m,d);
        mins(w.x1,ns[w.l].x1);
        mins(w.y1,ns[w.l].y1);
        maxs(w.x2,ns[w.l].x2);
        maxs(w.y2,ns[w.l].y2);
        w.r=build(m+1,r,d);
        mins(w.x1,ns[w.r].x1);
        mins(w.y1,ns[w.r].y1);
        maxs(w.x2,ns[w.r].x2);
        maxs(w.y2,ns[w.r].y2);
        return &w-ns;
    }
    inline int maxd(int v){
        if(!v)return 0;
        node&w=ns[v];
        return max0(X-w.x1)+max0(w.x2-X)+max0(Y-w.y1)+max0(w.y2-Y);
    }
    inline int mind(int v){
        if(!v)return inf;
        node&w=ns[v];
        return max0(X-w.x2)+max0(w.x1-X)+max0(Y-w.y2)+max0(w.y1-Y);
    }
    void nt(int v=1){
        node&w=ns[v];
        int a=abs(X-w.xm)+abs(Y-w.ym);
        if(a)mins(minv,a);
        int ld=mind(w.l);
        int rd=mind(w.r);
        if(ld<rd){
            if(ld<minv)nt(w.l);
            if(rd<minv)nt(w.r);
        }else{
            if(rd<minv)nt(w.r);
            if(ld<minv)nt(w.l);
        }
    }
    void ft(int v=1){
        node&w=ns[v];
        int a=abs(X-w.xm)+abs(Y-w.ym);
        if(a)maxs(maxv,a);
        int ld=maxd(w.l);
        int rd=maxd(w.r);
        if(ld>rd){
            if(ld>maxv)ft(w.l);
            if(rd>maxv)ft(w.r);
        }else{
            if(rd>maxv)ft(w.r);
            if(ld>maxv)ft(w.l);
        }
    }
    inline int read(){
        char c=getchar();
        int x=0;
        while(c>'9'||c<'0')c=getchar();
        while(c>='0'&&c<='9')
        x=x*10+c-'0',c=getchar();
        return x;
    }
    int main(){
        n=read();
        for(int i=0;i<n;i++)ps[i].x=read(),ps[i].y=read();
        build(0,n);
        for(int i=0;i<n;i++){
            X=ps[i].x;Y=ps[i].y;
            minv=inf;maxv=0;
            nt();
            ft();
            mins(ans,maxv-minv);
        }
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    Python 猜数小程序(练习)
    Mysql 字符串日期互转
    MaxCompute 语句笔记
    数据仓库架构
    Python 比较两个字符串的相似度
    Python print
    Python简单计算器
    HashMap为什么线程不安全(死循环+数据丢失过程分析)
    浅谈ArrayList、Vector和LinkedList
    JAVA对象的浅克隆和深克隆
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5137294.html
Copyright © 2020-2023  润新知