BZOJ 1052: [HAOI2007] coverage issue

Title description

Someone planted N small saplings on the mountain. Winter came, the temperature dropped rapidly, and the small saplings were fragile, so the owner wanted to
cover them with some thin plastic films. After a long thought, he decided to use 3 L L square plastic films Cover the little tree. We may wish to
establish a plane rectangular coordinate system for the mountain , and set the coordinate of the ith tree as (Xi, Yi).
The sides of the three L L squares must be parallel to the coordinate axis. If a point is on
the boundary of the square, Also counted as being covered. Of course, we hope that the smaller the area of ​​the plastic film, the better, that is, the minimum value of L.

Input

  The first line has a positive integer N, indicating how many trees there are. Next there are N rows, and the i + 1 row has 2 integers Xi, Yi, which represent the coordinates of the i-th tree, to ensure that
no two trees have the same coordinates.

Output

  One line, output the smallest L value.

Sample Input

4
0 1
0 -1
1 0
-1 0

Sample Output

1

HINT

100% data, N <= 20000

Consider greed.
Find a minimum rectangle first to enclose all points.
Then the first square must be covered by a corner of the rectangle. (You can list the situation to discuss)
Delete these covered points.
Then cover it with another one.
Finally, see if the rest can be framed by a square.

#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 << '\n';
    return 0;
}

Guess you like

Origin www.cnblogs.com/R-Q-R-Q/p/12700959.html