题意:
给出N个点,可以选其中四个点组成正方形,输出最大边长。其中。
思路:
容易想到如果知道两个点这个正方形就可以确定,但是N*N明显不行,这里又可以有一个剪枝,只需要枚举同行或者同列的点。
对于每个点哈希一下存在unordered_set里。
两重循环,外层枚举一个点,内层枚举跟它同行或同列的点,然后确定边长,在unordered_set找另外两个点存不存在。这里还是有很多重复计算,比如
1和2算的时候其实已经算了1和3的情况了,所以可以选同行同列中size小的那个。
还可以加个最优解剪枝。
代码:
const ll base=1e9+7;
struct point
{
int x,y;
}p[100010];
unordered_set<ll>s;
unordered_map<int,vector<int> >mpx,mpy;
int ans;
ll gethash(int x,int y)
{
return x*base+y;
}
int judge1(int x,int y,int z)
{
int d=abs(y-z);
if(d<=ans)return 0;
//if(s.count(gethash(x-d,y))&&s.count(gethash(x-d,z)))
//return d; 不用写否则会重复
if(s.count(gethash(x+d,y))&&s.count(gethash(x+d,z)))
return d;
return 0;
}
int judge2(int x,int y,int z)
{
int d=abs(y-z);
if(d<=ans)return 0;
//if(s.count(gethash(y,x-d))&&s.count(gethash(z,x-d)))
//return d;
if(s.count(gethash(y,x+d))&&s.count(gethash(z,x+d)))
return d;
return 0;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
s.clear();mpx.clear();mpy.clear();
for(int i=1;i<=n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
mpx[p[i].x].push_back(p[i].y);
mpy[p[i].y].push_back(p[i].x);
s.insert(gethash(p[i].x,p[i].y));
}
ans=0;
for(int i=1;i<=n;i++)
{
int len1=mpx[p[i].x].size();
int len2=mpy[p[i].y].size();
if(len1<len2)
{
for(int j=0;j<len1;j++)
ans=max(ans,judge1(p[i].x,p[i].y,mpx[p[i].x][j]));
}
else
{
for(int j=0;j<len2;j++)
ans=max(ans,judge2(p[i].y,p[i].x,mpy[p[i].y][j]));
}
}
printf("%d\n",ans);
}
return 0;
}
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!