這個題如果能想到的話還算簡單。。。
但是思路似乎。。。反正我想不出來
我們首先對於一堆點,記錄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;
}