1052: [HAOI2007]覆盖问题 - BZOJ

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.
View Code

 

posted @ 2014-04-08 14:42  Randolph87  阅读(216)  评论(0编辑  收藏  举报