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