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

 

你可能感兴趣的:(2007)