• [HAOI2007]覆盖问题


    题目描述

    某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄膜把这些小树遮盖起来,经过一番长久的思考,他决定 用3个L*L的正方形塑料薄膜将小树遮起来。我们不妨将山建立一个平面直角坐标系,设第i棵小树的坐标为(Xi,Yi),3个L*L的正方形的边要求平行 与坐标轴,一个点如果在正方形的边界上,也算作被覆盖。当然,我们希望塑料薄膜面积越小越好,即求L最小值。

    输入输出格式

    输入格式:

    第一行有一个正整数N,表示有多少棵树。

    接下来有N行,第i+1行有2个整数Xi,Yi,表示第i棵树的坐标,保证不会有2个树的坐标相同。

    输出格式:

    一行,输出最小的L值。

    输入输出样例

    输入样例#1: 复制
    4
    0 1
    0 -1
    1 0
    -1 0
    
    输出样例#1: 复制
    1

    说明

    数据范围

    100%的数据,-1,000,000,000<=Xi,Yi<=1,000,000,000

    30%的数据,N<=100

    50%的数据,N<=2000

    100%的数据,N<=20000

    二分答案ans

    求出最大的包括n个点的矩形

    说明至少有一个正方形与外包矩形有两条边及以上相接,就是一个公共角

    于是我们可以对于前两个正方形枚举与哪个角相接,对于第三个正方形判断就行了

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 using namespace std;
     7 typedef long long lol;
     8 struct Data
     9 {
    10   int top;
    11   int x[20001],y[20001];
    12 }a;
    13 int Minx,Miny,Maxx,Maxy,n,ans;
    14 void cut(Data &b,int x1,int x2,int y1,int y2)
    15 {int i;
    16   int tot=0;
    17   for(i=1;i<=b.top;i++)
    18     {
    19       if ((b.x[i]<x1||b.x[i]>x2)||(b.y[i]<y1||b.y[i]>y2))
    20       b.x[++tot]=b.x[i],b.y[tot]=b.y[i];
    21     }
    22   b.top=tot;
    23 }
    24 void work(Data &b,int c,int mid)
    25 {int i;
    26   Maxx=-1e9;Minx=1e9;
    27   Maxy=-1e9;Miny=1e9;
    28   for (i=1;i<=b.top;i++)
    29     {
    30       Maxx=max(Maxx,b.x[i]);Minx=min(Minx,b.x[i]);
    31       Maxy=max(Maxy,b.y[i]);Miny=min(Miny,b.y[i]);
    32     }
    33   if (c==1)
    34     {
    35       cut(b,Minx,Minx+mid,Miny,Miny+mid);
    36     }
    37   if (c==2)
    38     {
    39       cut(b,Minx,Minx+mid,Maxy-mid,Maxy);
    40     }
    41   if (c==3)
    42     {
    43       cut(b,Maxx-mid,Maxx,Maxy-mid,Maxy);
    44     }
    45   if (c==4)
    46     {
    47       cut(b,Maxx-mid,Maxx,Miny,Miny+mid);
    48     }
    49 }
    50 bool check(int mid)
    51 {int x,y,i,x1,y1,x2,y2;
    52   Data b;
    53   for (x=1;x<=4;x++)
    54     {
    55       for (y=1;y<=4;y++)
    56     {
    57       b.top=a.top;
    58       for (i=1;i<=b.top;i++)
    59         {
    60           b.x[i]=a.x[i];b.y[i]=a.y[i];
    61         }
    62       work(b,x,mid);work(b,y,mid);
    63       x1=-1e9;x2=1e9;
    64       y1=-1e9;y2=1e9;
    65       for (i=1;i<=b.top;i++)
    66         {
    67           x1=max(x1,b.x[i]);x2=min(x2,b.x[i]);
    68           y1=max(y1,b.y[i]);y2=min(y2,b.y[i]);
    69         }
    70       if (x1-x2<=mid&&y1-y2<=mid) return 1;
    71     }
    72     }
    73   return 0;
    74 }
    75 int main()
    76 {int i;
    77   cin>>n;
    78   for (i=1;i<=n;i++)
    79     {
    80       scanf("%d%d",&a.x[i],&a.y[i]);
    81     }
    82   a.top=n;
    83   int l=0,r=1e9;
    84   while (l<=r)
    85     {
    86       int mid=(l+r)/2;
    87       if (check(mid)) ans=mid,r=mid-1;
    88       else l=mid+1;
    89     }
    90   cout<<ans;
    91 }
  • 相关阅读:
    Hbase数据备份&&容灾方案
    maven 高级玩法
    Python操作MySQL -即pymysql/SQLAlchemy用法
    python
    Redis的AOF功能
    Redis的快照功能
    查看哪些进程占用了SWAP分区?
    Java进程CPU使用率高排查
    利用iptables实现基于端口的网络流量统计
    从free命令看Linux内存管理
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8496989.html
Copyright © 2020-2023  润新知