• [BZOJ1052][HAOI2007]覆盖问题 二分+贪心


    1052: [HAOI2007]覆盖问题

    Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2053  Solved: 959 [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

    用一个最小矩形框住所有点,L*L的矩形一定放在4角之一。

    枚举第一个放的位置,去掉已覆盖的,从新画最小矩形。

    再枚举第二个放的位置,去掉后判断剩下的点能否用一个L*L的矩形覆盖。

    二分L。

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<cstdlib>
     5 #include<algorithm>
     6 using namespace std;
     7 int n;
     8 struct data {
     9     int x,y;
    10 }a[20002];
    11 int vis[20002];
    12 int x1=2147483647,y1=2147483647,x2=-2147483640,y2=-2147483640;
    13 void cut(int x,int y,int l) {
    14     for(int i=1;i<=n;i++) if(a[i].x<=x+l&&a[i].x>=x&&a[i].y<=y+l&&a[i].y>=y) vis[i]=1;
    15 }
    16 void solve(int f,int l) {
    17     if(f==1) {
    18         int x=2147483647,y=2147483647;
    19         for(int i=1;i<=n;i++) {
    20             if(vis[i]) continue;
    21             x=min(x,a[i].x);y=min(y,a[i].y);
    22         }
    23         cut(x,y,l);
    24     }
    25     if(f==2) {
    26         int x=2147483647,y=-2147483640;
    27         for(int i=1;i<=n;i++) {
    28             if(vis[i]) continue;
    29             x=min(x,a[i].x);y=max(y,a[i].y);
    30         }
    31         cut(x,y-l,l);
    32     }
    33     if(f==3) {
    34         int x=-2147483640,y=-2147483640;
    35         for(int i=1;i<=n;i++) {
    36             if(vis[i]) continue;
    37             x=max(x,a[i].x);y=max(y,a[i].y);
    38         }
    39         cut(x-l,y-l,l);
    40     }
    41     if(f==4) {
    42         int x=-2147483647,y=2147483640;
    43         for(int i=1;i<=n;i++) {
    44             if(vis[i]) continue;
    45             x=max(x,a[i].x);y=min(y,a[i].y);
    46         }
    47         cut(x-l,y,l);
    48     }
    49 }
    50 bool check(int l) {
    51     for(int i=1;i<=4;i++) {
    52         for(int j=1;j<=4;j++) {
    53             memset(vis,0,sizeof(vis));
    54             solve(i,l);solve(j,l);
    55             int xx1=2147483647,yy1=2147483647,xx2=-2147483640,yy2=-2147483640;
    56             for(int i=1;i<=n;i++) {
    57                 if(vis[i])continue;
    58                 xx1=min(xx1,a[i].x);xx2=max(xx2,a[i].x);
    59                 yy1=min(yy1,a[i].y);yy2=max(yy2,a[i].y);
    60             }
    61             if(xx2-l<=xx1&&yy2-l<=yy1) return 1;
    62         }
    63     }
    64     return 0;
    65 }
    66 int main() {
    67     scanf("%d",&n);
    68     for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);
    69     int l=1,r=2147483640;
    70     while(l<=r) {
    71         int mid=(l+r)>>1;
    72         if(check(mid)) r=mid-1;
    73         else l=mid+1;
    74     }
    75     printf("%d",l);
    76 }
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    treap模板
    Codeforces Round #446 (Div. 2)
    BZOJ 1001: [BeiJing2006]狼抓兔子 (最小割)
    NOIP2017总结
    Python 操作 Mysql 模块
    poj 3660 Cow Contest (传递闭包)
    poj 1964 Cow Cycling(dp)
    poj 3671 Dining Cows (Dp)
    cogs 线型网络(状压dp)
    codevs 2800 送外卖(状压dp)
  • 原文地址:https://www.cnblogs.com/wls001/p/7683776.html
Copyright © 2020-2023  润新知