zoukankan      html  css  js  c++  java
  • 1052: [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
    数据范围
    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
  • 相关阅读:
    Rust入坑指南:亡羊补牢
    antirez:Redis6真的来了
    代码检查又一利器:ArchUnit
    【译】浅谈SOLID原则
    Rust入坑指南:鳞次栉比
    【译】什么才是优秀的代码
    Elasticsearch从入门到放弃:文档CRUD要牢记
    【译】利用Lombok消除重复代码
    Netty 中的心跳检测机制
    Netty 中的异步编程 Future 和 Promise
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3651969.html
Copyright © 2011-2022 走看看