Description
某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小树遮起来。我们不妨将山建立一个平面直角坐标系,设第i棵小树的坐标为(Xi,Yi),3个L*L的正方形的边要求平行与坐标轴,一个点如果在正方形的边界上,也算作被覆盖。当然,我们希望塑料薄膜面积越小越好,即求L最小值。
Input
第一行有一个正整数N,表示有多少棵树。接下来有N行,第i+1行有2个整数Xi,Yi,表示第i棵树的坐标,保证不会有2个树的坐标相同。
Output
一行,输出最小的L值。
Sample Input
4
0 1
0 -1
1 0
-1 0
Sample Output
1
数据范围
100%的数据,-1,000,000,000<=Xi,Yi<=1,000,000,000
30%的数据,N<=100
50%的数据,N<=2000
100%的数据,N<=20000
可以想到,二分答案,然后判断正确性
先用一个大矩形覆盖整个图,第一个正方形一定在这个大矩形的四个角上
然后删掉被覆盖的点,继续做,最后一个正方形就直接判断就行了
1 const 2 maxn=20010; 3 inf=1000000000; 4 type 5 point=record 6 x,y:longint; 7 end; 8 var 9 a:array[0..maxn]of point; 10 flag:array[0..maxn]of longint; 11 n,l,r,mid:longint; 12 13 procedure init; 14 var 15 i:longint; 16 begin 17 read(n); 18 for i:=1 to n do 19 with a[i] do 20 read(x,y); 21 end; 22 23 function max(x,y:longint):longint; 24 begin 25 if x>y then exit(x); 26 exit(y); 27 end; 28 29 function min(x,y:longint):longint; 30 begin 31 if x<y then exit(x); 32 exit(y); 33 end; 34 35 function try(x:longint):boolean; 36 var 37 maxx,maxy,minx,miny,i:longint; 38 begin 39 maxx:=-inf; 40 maxy:=-inf; 41 minx:=inf; 42 miny:=inf; 43 for i:=1 to n do 44 if flag[i]=0 then 45 begin 46 maxx:=max(maxx,a[i].x); 47 maxy:=max(maxy,a[i].y); 48 minx:=min(minx,a[i].x); 49 miny:=min(miny,a[i].y); 50 end; 51 if x=3 then 52 if (maxx-minx<=mid) and (maxy-miny<=mid) then exit(true) 53 else exit(false) 54 else 55 begin 56 for i:=1 to n do 57 if (a[i].x<=minx+mid) and (a[i].y<=miny+mid) then inc(flag[i]); 58 if try(x+1) then exit(true); 59 for i:=1 to n do 60 if (a[i].x<=minx+mid) and (a[i].y<=miny+mid) then dec(flag[i]); 61 for i:=1 to n do 62 if (a[i].x<=minx+mid) and (a[i].y>=maxy-mid) then inc(flag[i]); 63 if try(x+1) then exit(true); 64 for i:=1 to n do 65 if (a[i].x<=minx+mid) and (a[i].y>=maxy-mid) then dec(flag[i]); 66 for i:=1 to n do 67 if (a[i].x>=maxx-mid) and (a[i].y<=miny+mid) then inc(flag[i]); 68 if try(x+1) then exit(true); 69 for i:=1 to n do 70 if (a[i].x>=maxx-mid) and (a[i].y<=miny+mid) then dec(flag[i]); 71 for i:=1 to n do 72 if (a[i].x>=maxx-mid) and (a[i].y>=maxy-mid) then inc(flag[i]); 73 if try(x+1) then exit(true); 74 for i:=1 to n do 75 if (a[i].x>=maxx-mid) and (a[i].y>=maxy-mid) then dec(flag[i]); 76 exit(false); 77 end; 78 end; 79 80 procedure work; 81 var 82 i:longint; 83 begin 84 l:=1; 85 r:=inf*2; 86 while l<>r do 87 begin 88 mid:=(l+r)>>1; 89 for i:=1 to n do 90 flag[i]:=0; 91 if try(1) then r:=mid 92 else l:=mid+1; 93 end; 94 write(l); 95 end; 96 97 begin 98 init; 99 work; 100 end.