zoukankan      html  css  js  c++  java
  • bzoj1052 9.20考试 第二题 覆盖问题

    1052: [HAOI2007]覆盖问题

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2004  Solved: 937
    [Submit][Status][Discuss]

    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

      

      这道题当时一看还以为是一道几何题,就先放着最后打然后就华丽丽的爆零了。

      最后正解并不是我当初第一反应的几何,但确实是我当时第二反应——二分答案,exciting……

      我们可以通过一个无法用语言描述的证明可知至少有一个正方形是位于最小矩形的一个角上的。因为一共就三个正方形,所以我们dfs每个正方形位于当前最小矩形的四个角的情况就好了,那么时间复杂度就是O(log (2*10^9)*n*64)轻松搞掉。

     1 #include<iostream>
     2 #include<cstdlib>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<queue>
     6 #include<algorithm>
     7 #include<cmath>
     8 #include<map>
     9 #include<vector>
    10 #define N 20005
    11 using namespace std;
    12 int n,xx,nx,xy,ny;
    13 bool fw[N];
    14 struct no
    15 {
    16     int x,y;
    17 }node[N];
    18 bool dfs(long long L,int x,int sum)
    19 {
    20     if(sum==n)return 1;
    21     if(x==4)
    22         return 0;
    23     int xxx=-0x7fffffff,nnx=0x7fffffff,xxy=-0x7fffffff,nny=0x7fffffff;
    24     if(x==1)
    25         xxx=xx,nnx=nx,xxy=xy,nny=ny;
    26     else
    27     {
    28         for(int i=1;i<=n;i++)
    29         {
    30             if(fw[i])continue;
    31             if(node[i].x>xxx) xxx=node[i].x;
    32             if(node[i].x<nnx) nnx=node[i].x;
    33             if(node[i].y>xxy) xxy=node[i].y;
    34             if(node[i].y<nny) nny=node[i].y;
    35         }
    36     }
    37     bool b[N];
    38     int t=sum;
    39     memcpy(b,fw,sizeof(fw));
    40     for(int i=1;i<=n;i++)
    41     {
    42         if(!fw[i]&&node[i].x<=nnx+L&&node[i].y<=nny+L)
    43             fw[i]=1,t++;
    44     }
    45     if(dfs(L,x+1,t)) return 1;
    46     memcpy(fw,b,sizeof(b));
    47     t=sum;
    48     for(int i=1;i<=n;i++)
    49     {
    50         if(!fw[i]&&node[i].x<=nnx+L&&node[i].y>=xxy-L)
    51             fw[i]=1,t++;
    52     }
    53     if(dfs(L,x+1,t)) return 1;
    54  
    55     memcpy(fw,b,sizeof(b));
    56     t=sum;
    57     for(int i=1;i<=n;i++)
    58     {
    59         if(!fw[i]&&node[i].x>=xxx-L&&node[i].y<=nny+L)
    60             fw[i]=1,t++;
    61     }
    62     if(dfs(L,x+1,t)) return 1;
    63  
    64     t=sum;
    65     memcpy(fw,b,sizeof(b));
    66     for(int i=1;i<=n;i++)
    67     {
    68         if(!fw[i]&&node[i].x>=xxx-L&&node[i].y>=xxy-L)
    69             fw[i]=1,t++;
    70     }
    71     if(dfs(L,x+1,t)) return 1;
    72     memcpy(fw,b,sizeof(b));
    73     return 0;
    74 }
    75 int main()
    76 {
    77     scanf("%d",&n);
    78     xx=-0x7fffffff,nx=0x7fffffff,ny=0x7fffffff,xy=-0x7fffffff;
    79     for(int i=1;i<=n;i++)
    80     {
    81         scanf("%d%d",&node[i].x,&node[i].y);
    82         if(node[i].x>xx) xx=node[i].x;
    83         if(node[i].x<nx) nx=node[i].x;
    84         if(node[i].y>xy) xy=node[i].y;
    85         if(node[i].y<ny) ny=node[i].y;
    86         fw[i]=0;
    87     }
    88     long long li=0,ri=max(xy-ny,xx-nx);
    89     while(li<=ri)
    90     {
    91         long long mid=(li+ri)>>1;
    92         memset(fw,0,sizeof(fw));
    93         if(dfs(mid,1,0))ri=mid-1;
    94         else li=mid+1;
    95     }
    96     printf("%lld
    ",ri+1);
    97     return 0;
    98 }
    View Code
  • 相关阅读:
    梦幻如初,心不忘。
    整数集和求并
    ACTF 2014 Write up
    适用web的图片
    jqGrid
    angularjs
    【转载】FPGA异步时钟设计中的同步策略
    Cordic的学习之硬件实现
    Cordic的学习初步
    DDS---三角函数发生器的用法
  • 原文地址:https://www.cnblogs.com/liutianrui/p/7570248.html
Copyright © 2011-2022 走看看