题目描述
某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄
膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个LL的正方形塑料薄膜将小树遮起来。我们不妨将山建
立一个平面直角坐标系,设第i棵小树的坐标为(Xi,Yi),3个LL的正方形的边要求平行与坐标轴,一个点如果在
正方形的边界上,也算作被覆盖。当然,我们希望塑料薄膜面积越小越好,即求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;
}