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;
    }
    
  • 相关阅读:
    liferay常用api总结
    liferay增删改简单小练习
    MD5加密
    日期的工具类
    java生成随机六位数的验证码&随机生成十位数ValidCode码,用于邮件的验证&检查是不是符合为合法的中国的手机号码
    MyBaties
    网页的外观---CSS层叠样式表---03
    还在买鲜花送女神?手把手教你搭建3D立体相册网站,包女神稀饭
    Vue入门——常见指令及其详细代码示例
    什么是可串行化MVCC
  • 原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12700959.html
Copyright © 2011-2022 走看看