某人在山上种了N棵小树苗。冬天来了,温度急速下降,小树苗脆弱得不堪一击,于是树主人想用一些塑料薄
膜把这些小树遮盖起来,经过一番长久的思考,他决定用3个L*L的正方形塑料薄膜将小树遮起来。我们不妨将山建
立一个平面直角坐标系,设第i棵小树的坐标为(Xi,Yi),3个L*L的正方形的边要求平行与坐标轴,一个点如果在
正方形的边界上,也算作被覆盖。当然,我们希望塑料薄膜面积越小越好,即求L最小值。
一行,输出最小的L值。
100%的数据,N<=20000
题解:二分+dfs
二分答案然后判定长度是否可行,因为正方形区域一定是卡着剩余的点的两个边界的,所以枚举卡那个边界即可。
#include
#include
#include
#include
#include
#define N 20003
#define inf 1000000003
using namespace std;
int n,m,minn,maxn,vis[N];
struct data{
int x,y;
}a[N];
int cmp(data a,data b)
{
return a.x=xmax-x&&a[i].y>=ymax-x) vis[i]=t;
if (dfs(x,t+1)) f=true;
for (int i=1;i<=n;i++)
{
if (vis[i]==t) vis[i]=0;
if (!vis[i]&&a[i].x<=xmin+x&&a[i].y<=ymin+x) vis[i]=t;
}
if (dfs(x,t+1)) f=true;
for (int i=1;i<=n;i++) {
if (vis[i]==t) vis[i]=0;
if (!vis[i]&&a[i].x<=xmin+x&&a[i].y>=ymax-x) vis[i]=t;
}
if (dfs(x,t+1)) f=true;
for (int i=1;i<=n;i++) {
if (vis[i]==t) vis[i]=0;
if (!vis[i]&&a[i].x>=xmax-x&&a[i].y<=ymin+x) vis[i]=t;
}
if (dfs(x,t+1)) f=true;
for (int i=1;i<=n;i++) if (vis[i]==t) vis[i]=0;
if (f) return 1;
return 0;
}
int main()
{
freopen("cover.in","r",stdin);
freopen("cover.out","w",stdout);
scanf("%d",&n);
maxn=-inf; minn=inf;
for (int i=1;i<=n;i++)
scanf("%d%d",&a[i].x,&a[i].y),maxn=max(maxn,a[i].x),maxn=max(maxn,a[i].y),
minn=min(minn,a[i].x),minn=min(minn,a[i].y);
sort(a+1,a+n+1,cmp);
int l=0; int r=maxn-minn+1;
int ans=r;
while (l<=r) {
int mid=(l+r)/2;
memset(vis,0,sizeof(vis));
if (dfs(mid,1)) ans=min(ans,mid),r=mid-1;
else l=mid+1;
}
printf("%d\n",ans);
}