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

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.
View Code
posted @ 2017-01-24 08:30  GhoStreach  阅读(75)  评论(0编辑  收藏