BZOJ1052:[HAOI2007]覆盖问题
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
0 1
0 -1
1 0
-1 0
Sample Output
1
HINT
100%的数据,N<=20000
题解:
贪心题,虽然我并不能完备地证明。
把没有覆盖的树苗所在的最小矩形区域表示出来,则一定在矩形的四个角上选择一个作为覆盖区域。重复操作3次,若成功覆盖,则可行。
代码:
1 uses math; 2 var 3 i,j,k,l,r,n,m,x1,x2,y1,y2,mid,ans:longint; 4 a:array[0..20001,0..2]of longint; 5 function ss(x,le:longint):boolean; 6 var i,j,k,l,x1,x2,y1,y2:longint; 7 aa:array[0..20001]of longint; 8 begin 9 l:=0; 10 for i:=1 to n do aa[i]:=a[i,0]; 11 x1:=maxlongint; y1:=maxlongint; x2:=-x1; y2:=-y1; 12 for i:=1 to n do 13 if aa[i]=0 then 14 begin 15 x1:=min(x1,a[i,1]); 16 y1:=min(y1,a[i,2]); 17 x2:=max(x2,a[i,1]); 18 y2:=max(y2,a[i,2]); 19 end; 20 if(x1=maxlongint)or(y1=maxlongint)then exit(true); 21 if x=0 then 22 begin 23 if(y2-y1<=le)and(x2-x1<=le)then exit(true); 24 exit(false); 25 end; 26 j:=x1; k:=y1; 27 for i:=1 to n do 28 if a[i,0]=0 then 29 if(a[i,1]>=j)and(a[i,1]<=j+le)and(a[i,2]>=k)and(a[i,2]<=k+le) 30 then a[i,0]:=1; 31 if ss(x-1,le)then l:=1; 32 for i:=1 to n do a[i,0]:=aa[i]; 33 j:=x1; k:=y2-le; 34 for i:=1 to n do 35 if a[i,0]=0 then 36 if(a[i,1]>=j)and(a[i,1]<=j+le)and(a[i,2]>=k)and(a[i,2]<=k+le) 37 then a[i,0]:=1; 38 if ss(x-1,le)then l:=1; 39 for i:=1 to n do a[i,0]:=aa[i]; 40 j:=x2-le; k:=y2-le; 41 for i:=1 to n do 42 if a[i,0]=0 then 43 if(a[i,1]>=j)and(a[i,1]<=j+le)and(a[i,2]>=k)and(a[i,2]<=k+le) 44 then a[i,0]:=1; 45 if ss(x-1,le)then l:=1; 46 for i:=1 to n do a[i,0]:=aa[i]; 47 j:=x2-le; k:=y1; 48 for i:=1 to n do 49 if a[i,0]=0 then 50 if(a[i,1]>=j)and(a[i,1]<=j+le)and(a[i,2]>=k)and(a[i,2]<=k+le) 51 then a[i,0]:=1; 52 if ss(x-1,le)then l:=1; 53 for i:=1 to n do a[i,0]:=aa[i]; 54 if l=1 then exit(true); 55 exit(false); 56 end; 57 begin 58 readln(n); 59 for i:=1 to n do 60 begin 61 readln(a[i,1],a[i,2]); 62 end; 63 l:=1; r:=maxlongint-1; ans:=maxlongint; 64 while l<=r do 65 begin 66 mid:=(l+r)div 2; 67 if ss(2,mid)then begin ans:=mid; r:=mid-1; end 68 else l:=mid+1; 69 end; 70 writeln(ans); 71 end.