• BZOJ 1941: [Sdoi2010]Hide and Seek KDtree + 估价函数


    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

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

    题解: 求对于每个点最远距离-最近距离的最小值, 依次枚举距离每个点最远距离与最近距离即可.

    #include<bits/stdc++.h>
    #define maxn 200000
    #define inf 1000000000 
    using namespace std;
    void getmin(int &a,int b) { if(b<a) a=b;  }
    void getmax(int &a,int b) { if(b>a) a=b;  }
    void setIO(string s)
    {
        string in=s+".in"; 
        string out=s+".out"; 
        freopen(in.c_str(),"r",stdin); 
        freopen(out.c_str(),"w",stdout);   
    }
    namespace KDtree
    {
        #define lson t[x].ch[0]
        #define rson t[x].ch[1] 
        #define mid ((l+r)>>1)
        int d,ansmin,ansmax,answer;      
        struct Node
        {
            int ch[2],minv[2],maxv[2],p[2]; 
        }t[maxn],T;   
        bool cmp(Node a,Node b)
        {
            if(a.p[d] == b.p[d]) return a.p[d^1] < b.p[d^1]; 
            return a.p[d] < b.p[d]; 
        }        
        void pushup(int o,int x)
        {
            getmin(t[o].minv[0], t[x].minv[0]); 
            getmax(t[o].maxv[0], t[x].maxv[0]); 
            getmin(t[o].minv[1], t[x].minv[1]); 
            getmax(t[o].maxv[1], t[x].maxv[1]);                           
        }
        int build(int l,int r,int o)
        {
            d=o; 
            nth_element(t+l,t+mid,t+1+r,cmp); 
            t[mid].minv[0]=t[mid].maxv[0]=t[mid].p[0]; 
            t[mid].minv[1]=t[mid].maxv[1]=t[mid].p[1];  
            t[mid].ch[0]=t[mid].ch[1]=0; 
            if(l<mid) 
            {
                t[mid].ch[0]=build(l,mid-1,o^1); 
                pushup(mid,t[mid].ch[0]); 
            }
            if(r>mid) 
            {
                t[mid].ch[1]=build(mid+1,r,o^1); 
                pushup(mid,t[mid].ch[1]);         
            }
            return mid;   
        }
        int _min(Node a)
        {
            int ans=0;                      
            for(int i=0;i<2;++i)
            {
                ans += max(T.p[i]-a.maxv[i], 0); 
                ans += max(a.minv[i]-T.p[i], 0);            
            }
            return ans; 
        }
        int _max(Node a)
        {
            int ans=0; 
            for(int i=0;i<2;++i)
            {
                ans += max(abs(T.p[i]-a.minv[i]), abs(T.p[i]-a.maxv[i])); 
            }
            return ans; 
        }
        void qmin(int x,int x1,int y1)
        {
            int dn=abs(t[x].p[0]-x1) + abs(t[x].p[1]-y1),dl,dr; 
            if(dn>0) getmin(ansmin,dn); 
            dl=lson?_min(t[lson]):inf; 
            dr=rson?_min(t[rson]):inf;   
            if(dl<dr)
            {
                if(dl<ansmin) qmin(lson,x1,y1);        
                if(dr<ansmin) qmin(rson,x1,y1); 
            }
            else
            {
                if(dr<ansmin) qmin(rson,x1,y1); 
                if(dl<ansmin) qmin(lson,x1,y1);        
            }
        }
        void qmax(int x,int x1,int y1)
        {
            int dn=abs(t[x].p[0]-x1) + abs(t[x].p[1]-y1),dl,dr; 
            getmax(ansmax, dn); 
            dl=lson?_max(t[lson]):-inf; 
            dr=rson?_max(t[rson]):-inf; 
            if(dl>dr) 
            {
                if(dl>ansmax) qmax(lson,x1,y1); 
                if(dr>ansmax) qmax(rson,x1,y1); 
            }
            else 
            {
                if(dr>ansmax) qmax(rson,x1,y1); 
                if(dl>ansmax) qmax(lson,x1,y1); 
            }
        }
        void solve(int i,int rt)
        {
            T=t[i], ansmin=inf,ansmax=-inf;   
            qmin(rt, T.p[0], T.p[1]); 
            qmax(rt, T.p[0], T.p[1]); 
            getmin(answer, ansmax-ansmin);              
        }
    }; 
    int main()
    {
        //setIO("A");       
        int n,root,i;
        KDtree::answer=inf; 
        scanf("%d",&n);          
        for(i=1;i<=n;++i) 
            scanf("%d%d",&KDtree::t[i].p[0],&KDtree::t[i].p[1]);  
        root=KDtree::build(1,n,0); 
        for(i=1;i<=n;++i)      
        { 
            KDtree::solve(i,root); 
        }      
        printf("%d
    ",KDtree::answer); 
        return 0; 
    }
    

      

  • 相关阅读:
    Set,List,Map,Vector,ArrayList的区别
    关于List,Set,Map能否存储null
    JAVA集合 DelayQueue 的使用 (同步的超时队列)
    FluentScheduler .Net 定时Job
    BeanFactory和FactoryBean
    ansj 分词,超过了标准的 IK 分词.
    Python字典、集合结构详解
    Python列表、元组结构详解
    C语言--结构体&文件
    C语言--指针
  • 原文地址:https://www.cnblogs.com/guangheli/p/11054479.html
Copyright © 2020-2023  润新知