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;
}
原文地址:https://www.cnblogs.com/R-Q-R-Q/p/12700959.html