• 【BZOJ 1052】 1052: [HAOI2007]覆盖问题 (乱搞)


    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

    HINT

    100%的数据,N<=20000

    Source

    【分析】

      为什么黄学长称之为贪心。。?不懂。。

      首先我们用一个最小的矩形把所有点框住(这个很容易求吧?),

      如果答案的正方形边长等于这个矩形的宽,那么肯定有两个正方形是推到两边的,就是至少有一个正方形的顶点是矩形的顶点。

      如果正方形边长小于宽,因为矩形每条边至少有一个点,所以一定有一个正方形覆盖了矩形两条边,那么这个至少也有一个正方形的顶点是矩形的顶点。

      大于宽就不用说了吧?

      那么我们先二分答案,然后就枚举矩形的四个角,把覆盖的点删掉,递归做子问题就可以了。

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 #define Maxn 20010
     8 #define INF 0xfffffff
     9 
    10 int mymin(int x,int y) {return x<y?x:y;}
    11 int mymax(int x,int y) {return x>y?x:y;}
    12 
    13 struct node
    14 {
    15     int x,y;
    16     int p;
    17 }t[Maxn];
    18 
    19 int n,tot;
    20 
    21 void change(int x,int y,int nw,int L)
    22 {
    23     for(int i=1;i<=n;i++) if(t[i].x>=x&&t[i].y>=y&&t[i].p==0)
    24     {
    25         if(t[i].x-x>L||t[i].y-y>L) continue;
    26         t[i].p=nw;tot--;
    27     }
    28 }
    29 
    30 void change2(int nw)
    31 {
    32     for(int i=1;i<=n;i++) if(t[i].p==nw) 
    33     {
    34         t[i].p=0;
    35         tot++;
    36     }
    37 }
    38 
    39 bool check(int L,int nw)
    40 {
    41     if(tot==0) return 1;
    42     int x1=INF,x2=-INF,y1=INF,y2=-INF;
    43     for(int i=1;i<=n;i++) if(t[i].p==0)
    44     {
    45         x1=mymin(x1,t[i].x);x2=mymax(x2,t[i].x);
    46         y1=mymin(y1,t[i].y);y2=mymax(y2,t[i].y);
    47     }
    48     if(nw==1) return mymax(x2-x1,y2-y1)<=L;
    49     int nx,ny;
    50     bool ok=0;
    51     nx=x1,ny=y1;change(nx,ny,nw,L);
    52     if(check(L,nw-1)) ok=1;change2(nw);
    53     if(ok) return 1;
    54     
    55     nx=x1,ny=y2-L;change(nx,ny,nw,L);
    56     if(check(L,nw-1)) ok=1;change2(nw);
    57     if(ok) return 1;
    58     
    59     nx=x2-L,ny=y1;change(nx,ny,nw,L);
    60     if(check(L,nw-1)) ok=1;change2(nw);
    61     if(ok) return 1;
    62     
    63     nx=x2-L,ny=y2-L;change(nx,ny,nw,L);
    64     if(check(L,nw-1)) ok=1;change2(nw);
    65     if(ok) return 1;
    66     return 0;
    67 }
    68 
    69 int main()
    70 {
    71     scanf("%d",&n);
    72     for(int i=1;i<=n;i++)
    73     {
    74         scanf("%d%d",&t[i].x,&t[i].y);
    75         t[i].p=0;
    76     }
    77     int l=1,r=INF;
    78         tot=n;
    79     while(l<r)
    80     {
    81         int mid=(l+r)>>1;
    82         if(check(mid,3)) r=mid;
    83         else l=mid+1;
    84     }
    85     printf("%d
    ",l);
    86     return 0;
    87 }
    View Code

    2017-02-22 14:07:58

  • 相关阅读:
    Android碰撞检测——Region碰撞检查
    游戏音乐MediaPlayer和SoundPool常用的一些方法
    游戏框架SurfaceView的简单运用
    Android碰撞检测——矩形检查
    View框架下实现角色的上下左右移动
    数据库导出到Excel前后端代码
    jQuery打印插件PrintArea实现
    showModalDialog 传值及刷新
    文件夹中文件夹(文件)按时间排序,读取最新的文件夹(文件)
    .NET分布式开发报错:“与基础事务管理器的通信失败”的解决方法
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6428623.html
Copyright © 2020-2023  润新知