ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

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\n%d\n",a0*2,ans*2);
    return 0;
}

 

posted on 2016-06-21 12:58  nul  阅读(581)  评论(0编辑  收藏  举报