BZOJ_1052_[HAOI2007]_覆盖问题_(二分+贪心)
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=1052
网格图,给出\(n\)个点,要求用3个边长相同的正方形覆盖所有点,求最小边长.
分析
显然是二分+判断可行性.
如何判断可行性呢?我们注意到是3个正方形.为什么是3个?
我们先找出覆盖所有点的最小距形,那么距形的四条边必须有正方形贴着,而又是3个正方形,所以至少要有1个正方形同时贴着两条边.
1.贴着的边相对
这样的话三个正方形都同时贴着相对的两条边,比如是上下两条边,那么贴着左边的那个正方形就贴着3条边,在距形的一角.
2.贴着的边相邻
这样的话这个正方形就在距形的一角.
所以我们递归的把正方形放在距形的一角,然后去掉已经覆盖了的点,继续放正方形即可.
1 #include <bits/stdc++.h> 2 #define fst first 3 #define scd second 4 using namespace std; 5 inline int read(int &x){x=0;int k=1;char c;for(c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')k=-1;for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';return x*=k;} 6 7 typedef pair <int,int> P; 8 const int maxn=20000+5,INF=0x7fffffff; 9 int n,ml,mr,mu,md; 10 P a[maxn]; 11 bool vis[maxn]; 12 bool dfs(int x,int t){ 13 if(t==3) return max(md-mu,mr-ml)<=x; 14 P b[4][2]; 15 b[0][0]=P(ml,mu),b[0][1]=P(ml+x,mu+x); 16 b[1][0]=P(ml,md-x),b[1][1]=P(ml+x,md); 17 b[2][0]=P(mr-x,mu),b[2][1]=P(mr,mu+x); 18 b[3][0]=P(mr-x,md-x),b[3][1]=P(mr,md); 19 for(int i=0;i<4;i++){ 20 int tl=ml,tr=mr,tu=mu,td=md; 21 int tmp[maxn]; 22 for(int j=1;j<=n;j++) tmp[j]=vis[j]; 23 for(int j=1;j<=n;j++) 24 if(a[j].fst>=b[i][0].fst&&a[j].fst<=b[i][1].fst&&a[j].scd>=b[i][0].scd&&a[j].scd<=b[i][1].scd) 25 vis[j]=true; 26 mu=ml=INF; mr=md=-INF; 27 for(int j=1;j<=n;j++)if(!vis[j]){ 28 mu=min(mu,a[j].scd); md=max(md,a[j].scd); 29 ml=min(ml,a[j].fst); mr=max(mr,a[j].fst); 30 } 31 bool flag=dfs(x,t+1); 32 ml=tl,mr=tr,mu=tu,md=td; 33 for(int j=1;j<=n;j++) vis[j]=tmp[j]; 34 if(flag) return true; 35 } 36 return false; 37 } 38 inline void solve(){ 39 int l=0,r=max(md-mu,mr-ml); 40 while(l<r){ 41 for(int i=1;i<=n;i++)if(vis[i]) puts("!"); 42 int mid=l+(r-l)/2; 43 if(dfs(mid,1)) r=mid; 44 else l=mid+1; 45 } 46 printf("%d\n",l); 47 } 48 inline void init(){ 49 read(n); 50 mu=ml=INF,mr=md=-INF; 51 for(int i=1;i<=n;i++){ 52 read(a[i].fst), read(a[i].scd); 53 ml=min(ml,a[i].fst); mr=max(mr,a[i].fst); 54 mu=min(mu,a[i].scd); md=max(md,a[i].scd); 55 } 56 } 57 int main(){ 58 init(); 59 solve(); 60 return 0; 61 }
1052: [HAOI2007]覆盖问题
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1540 Solved: 705
[Submit][Status][Discuss]
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
Source