zoukankan      html  css  js  c++  java
  • BZOJ 1052: [HAOI2007]覆盖问题

    题目描述

    某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄
    膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个LL的正方形塑料薄膜将小树遮起来。我们不妨将山建
    立一个平面直角坐标系,设第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

    考虑贪心。
    先找出一个最小矩形能将所有的点都围起来。
    那么第一个正方形一定是盖在了矩形的某一个角。(可以列出情况讨论一下)
    把这些被覆盖的点删去。
    然后再用一个覆盖一次。
    最后看剩下的能否用一个正方形框住即可。

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<bitset>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    typedef long long LL;
    const int N = 20010;
    inline int read()
    {
        register int x = 0 , f = 0; register char c = getchar();
        while(c < '0' || c > '9') f |= c == '-' , c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0' , c = getchar();
        return f ? -x : x;
    }
    int mid;
    struct Node
    {
        int n;
        int x[N] , y[N];
    }A , B;
     
    void cut(int min_x , int min_y , int max_x , int max_y)
    {
        int tot = 0;
        for(int i = 1 ; i <= B.n ; ++i) 
            if(B.x[i] < min_x || B.x[i] > max_x || B.y[i] < min_y || B.y[i] > max_y)
                B.x[++tot] = B.x[i] , B.y[tot] = B.y[i];
        B.n = tot; return ; 
    }
     
    void solve(int op)
    {
        int max_x = -1e9 , max_y = -1e9 , min_x = 1e9 , min_y = 1e9;
        for(int i = 1 ; i <= B.n ; ++i) 
            max_x = max(max_x , B.x[i]) , min_x = min(min_x , B.x[i]) , max_y = max(max_y , B.y[i]) , min_y = min(min_y , B.y[i]);
        if(op == 1) cut(min_x , min_y , min_x + mid , min_y + mid);
        if(op == 2) cut(max_x - mid , min_y , max_x , min_y + mid);
        if(op == 3) cut(max_x - mid , max_y - mid , max_x , max_y);
        if(op == 4) cut(min_x , max_y - mid , min_x + mid , max_y);
        return ;
    }
     
    bool check()
    {
        for(int x = 1 ; x <= 4 ; ++x) for(int y = 1 ; y <= 4 ; ++y)
        {
            B = A;
            solve(x); solve(y);
            int max_x = -1e9 , max_y = -1e9 , min_x = 1e9 , min_y = 1e9;
            for(int i = 1 ; i <= B.n ; ++i) 
                max_x = max(max_x , B.x[i]) , min_x = min(min_x , B.x[i]) , max_y = max(max_y , B.y[i]) , min_y = min(min_y , B.y[i]);
            if(max_x - min_x <= mid && max_y - min_y <= mid) return true;
        }
        return false;
    }
     
    int main()
    {
        A.n = read();
        for(int i = 1 ; i <= A.n ; ++i) A.x[i] = read() , A.y[i] = read();
        int l = 0 , r = 1e9 , ans = -1;
        while(l <= r)
        {
            mid = (l + r) >> 1;
            if(check()) r = mid - 1 , ans = mid; else l = mid + 1;
        }
        cout << ans << '
    ';
        return 0;
    }
    
  • 相关阅读:
    Xcode 自定义代码段
    Foundation和CoreFoundation之间的转换
    如何由新特性跳转到App首页
    判断是否是新特性,决定是否进入欢迎页
    iOS面试题01
    公司生日聚会-水长城之游
    jquery操作html元素之(设置内容和属性)
    jquery操作html元素之( 获得内容和属性)
    解决:Map的area属性标签鼠标Hover可以给area加背景
    在网页制作中,面对设计图,网页制作人员一般要遵循的原则是什么?
  • 原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12700959.html
Copyright © 2011-2022 走看看