这个题如果能想到的话还算简单。。。
但是思路似乎。。。反正我想不出来
我们首先对于一堆点,记录xy分别的min和Max,一共四个值
当正方形数目小于等于三个的时候,其中一个正方形一定以这四个点中的一个点为顶点
然后枚举就好了。。。
自己写的代码打死都过不去,后来进入了无意义的发呆调试。。所以后来看了别人的代码。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define inf 0x7fffffff/2
#define MIN -inf
#define MAX 20009
#define ll long long
#define rep(i,j,k) for(int i=j;i<=k;i++)
using namespace std;
int n,done[MAX],now=0;
int x[5],y[4];
int vis[MAX],ans;
struct point
{
int x,y;
}a[MAX];
bool check(int len)
{
rep(i,0,1)
rep(j,0,1)
{
int sum=0,sum2,now_x=x[i],now_y=y[j];
int xx[2]={inf,-inf},yy[2]={inf,-inf};
memset(done,0,sizeof(done));
rep(k,1,n)
if(abs(a[k].x-now_x)<=len&&abs(a[k].y-now_y)<=len)
done[k]=1,sum++;
else
xx[0]=min(xx[0],a[k].x),
xx[1]=max(xx[1],a[k].x),
yy[0]=min(yy[0],a[k].y),
yy[1]=max(yy[1],a[k].y);
if(sum==n)
return 1;
rep(k,0,1)
rep(p,0,1)
{
int sum2=sum;
now_x=xx[k],now_y=yy[p];
int maxx=-inf,minx=inf,maxy=-inf,miny=inf;
rep(l,1,n)
if(!done[l])
if(abs(a[l].x-now_x)<=len&&abs(a[l].y-now_y)<=len)
sum2++;
else
maxx=max(maxx,a[l].x),
minx=min(minx,a[l].x),
maxy=max(maxy,a[l].y),
miny=min(miny,a[l].y);
if(sum2==n)
return 1;
if(maxx-minx<=len&&maxy-miny<=len)
return 1;
}
}
return 0;
}
int main()
{
scanf("%d",&n);
x[0]=y[0]=inf;
x[1]=y[1]=-inf;
rep(i,1,n)
scanf("%d%d",&a[i].x,&a[i].y),
x[0]=min(x[0],a[i].x),x[1]=max(x[1],a[i].x),
y[0]=min(y[0],a[i].y),y[1]=max(y[1],a[i].y);
int l=0,r=1000000000;
while(l<r-1)
{
int mid=(l+r)>>1,t=check(mid);
printf("%d %d %d %d\n",l,mid,r,t);
if(t)
ans=mid,r=mid;
else
l=mid;
}
printf("%d\n",check(l)?l:r);
return 0;
}