• bzoj2675: Bomb


    Description

      A国和B国是两个超级大国,长期处于冷战状态;
      A国在B国中设有N个情报站,编号为1,2,3,……,N,每个情报站有一个坐标(Xi,Yi)。
      但是,A国的工作人员发现,每个情报站里都被埋上了炸弹!
      这些炸弹非常特殊,只要同时拆除其中的三个炸弹,所有炸弹就都不会爆炸了。
      由于各个情报站联络需要代价,拆除炸弹需要花费的总代价为这些炸弹两两之间的曼哈顿距离和。
      现在A国的指挥部门找到了你,希望知道可能需要的最大代价和最小代价。

    Input

      输入的第一行包含一个整数N。接下来N行,第i+1行两个整数Xi,Yi,表示第i个情报站的坐标。

    Output

      输出两行,每行包含一个整数,第一行表示可能的最大代价,第二行表示可能的最小代价。
    首先三个点(x1,y1),(x2,y2),(x3,y3)的两两曼哈顿距离和为2(max(x1,x2,x3)+max(y1,y2,y3)-min(x1,x2,x3)-min(y1,y2,y3))
    最大代价可以贪心,记录xmax,xmin,ymax,ymin,(x+y)max,(x+y)min,(x-y)max,(x-y)min
    答案为max{(x+y)max-xmin-ymin,xmax+ymax-(x+y)min,(x-y)max-xmin+ymax,xmax-ymin-(x-y)min}
    最小代价可以分治求,但可能被卡,所以加上随机化而不是每次取中位数分割
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    inline int _int(){
        int x=0,c=getchar();
        while(c>57||c<48)c=getchar();
        while(c>47&&c<58)x=x*10+c-48,c=getchar();
        return x;
    }
    const int inf=1000000000;
    int n,ans=inf,a0=0,x1=inf,x2=-inf,y1=inf,y2=-inf,a1=inf,a2=-inf,b1=inf,b2=-inf;
    struct pos{
        int x,y;
    }ps[100010],ms[100010];
    bool operator<(pos a,pos b){
        return a.x!=b.x?a.x<b.x:a.y<b.y;
    }
    bool cmp(pos a,pos b){
        return a.y!=b.y?a.y<b.y:a.x<b.x;
    }
    inline int abs(int a){
        return a>0?a:-a;
    }
    inline void mins(int&a,int b){if(a>b)a=b;}
    inline void maxs(int&a,int b){if(a<b)a=b;}
    inline int mx(int a,int b,int c){
        int x=a,y=a;
        mins(x,b);maxs(y,b);
        mins(x,c);maxs(y,c);
        return y-x;
    }
    void calc(int L,int R){
        if(R-L<12){
            for(int i=L;i<R;i++)for(int j=L;j<i;j++)for(int k=L;k<j;k++){
                int c=mx(ps[i].x,ps[j].x,ps[k].x)+mx(ps[i].y,ps[j].y,ps[k].y);
                if(c<ans)ans=c;
            }
            return;
        }
        int M=(R-L>100?L+rand()%(R-L):L+R>>1);
        std::nth_element(ps+L,ps+M,ps+R);
        int xm=ps[M].x;
        if(rand()&1){calc(L,M);calc(M,R);}
        else{calc(M,R);calc(L,M);}
        int p=0;
        for(int i=L;i<R;i++)if(abs(xm-ps[i].x)<ans)ms[p++]=ps[i];
        std::sort(ms,ms+p,cmp);
        L=0;
        for(R=2;R<p;R++){
            while(abs(ms[R].y-ms[L].y)>=ans)++L;
            for(int j=L;j<R;j++)for(int k=L;k<j;k++){
                int c=mx(ms[R].x,ms[j].x,ms[k].x)+mx(ms[R].y,ms[j].y,ms[k].y);
                if(c<ans)ans=c;
            }
        }
    }
    int main(){
        srand(13999);
        n=_int();
        for(int i=0;i<n;i++){
            int x=_int(),y=_int();
            mins(x1,x);maxs(x2,x);
            mins(y1,y);maxs(y2,y);
            mins(a1,x+y);maxs(a2,x+y);
            mins(b1,x-y);maxs(b2,x-y);
            ps[i]=(pos){x,y};
        }
        maxs(a0,a2-x1-y1);
        maxs(a0,x2+y2-a1);
        maxs(a0,b2-x1+y2);
        maxs(a0,x2-y1-b1);
        calc(0,n);
        printf("%d
    %d
    ",a0*2,ans*2);
        return 0;
    }
  • 相关阅读:
    大规模web服务读书笔记 狼
    MVC3如果虚拟目录中有点号,会导致静态文件404 狼
    CDN服务商和CDN常见问题 狼
    中文字段名,问题根源查询无聊话题。 狼
    NET下Session共享的几种实现方式 狼
    企业应用架构读书笔记与总结 狼
    Redis简单本机测试 狼
    你是否经历过这些,求如何继续才能提升 狼
    WinDbg配置和使用基础
    Python IDLE入门
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5603283.html
Copyright © 2020-2023  润新知