[HAOI2007]覆盖问题
Description
某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄
膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小树遮起来。我们不妨将山建
立一个平面直角坐标系,设第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
0 1
0 -1
1 0
-1 0
Sample Output
1
HINT
100%的数据,N<=20000
很显然,二分搜索,找出每次点的上下左右进行递归判断,当层数大于3的时候就返回。
#include <iostream> #include <algorithm> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <stack> #include <cstdlib> #include <iomanip> #include <cmath> #include <cassert> #include <ctime> #include <cstdlib> #include <map> #include <set> using namespace std; #pragma comment(linker, "/stck:1024000000,1024000000") #define lowbit(x) (x&(-x)) #define max(x,y) (x>=y?x:y) #define min(x,y) (x<=y?x:y) #define MAX 100000000000000000 #define MOD 1000 #define pi acos(-1.0) #define ei exp(1) #define PI 3.1415926535897932384626433832 #define ios() ios::sync_with_stdio(true) #define INF 1044266558 #define mem(a) (memset(a,0,sizeof(a))) #define inf 2e9 typedef long long ll; int x[20005],y[20005],n,vis[20005]; void check(int xl,int xr,int yd,int yu,int depth) { for(int i=0;i<n;i++) { if(!vis[i] && x[i]>=xl && x[i]<=xr && y[i]>=yd && y[i]<=yu) vis[i]=depth; } } bool dfs(int depth,int mid) { int xl=inf,xr=-inf,yu=-inf,yd=inf; for(int i=1;i<=n;i++) { if(vis[i]) continue; xl=min(xl,x[i]); xr=max(xr,x[i]); yd=min(yd,y[i]); yu=max(yu,y[i]); } if(max(xr-xl,yu-yd)<=mid) return true; if(depth==3) return false; for(int i=1;i<=2;i++) { for(int j=1;j<=2;j++) { if(i==1) { if(j==1) check(xl,xl+mid,yd,yd+mid,depth); else check(xl,xl+mid,yu-mid,yu,depth); } else { if(j==1) check(xr-mid,xr,yd,yd+mid,depth); else check(xr-mid,xr,yu-mid,yu,depth); } if(dfs(depth+1,mid)) return true; for(int k=1;k<=n;k++) if(vis[k]==depth) vis[k]=false; } } return false; } bool solve(int mid) { memset(vis,false,sizeof(vis)); return dfs(1,mid); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&x[i],&y[i]); } int l=0,mid,top,r=inf; while(l<=r) { mid=(l+r)>>1; if(solve(mid)){top=mid;r=mid-1;} else l=mid+1; } printf("%d\n",top); return 0; }