分析:给你一些点,让你求距离最大的两个点之前距离的平方。首先求出凸包,然后可以枚举凸包上所有顶点的距离找到最大值,也可以用旋转卡壳来求凸包直径。后者原理网上很多,解释的也挺好,我就放下我的代码就好了。
# include <stdio.h>
# include <algorithm>
using namespace std;
struct point
{
int x,y;
}v[50005];
int max(int a,int b)
{
return a>b?a:b;
}
int Cross(point a,point b,point c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
int Dis2(point a,point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int cmp(point a,point b)
{
int t=Cross(v[0],a,b);
if(t!=0)
return t>0?1:0;
return Dis2(v[0],a)<Dis2(v[0],b);
}
int rotating_calipers(point stack[50005],int top)//旋转卡壳
{//这里stack数组从0到top依次保存的是凸包从最下角逆时针无共线的顶点的次序。
int i,p,q=1,ans=0;
top++;
for(p=0;p<top;p++)
{//寻找以p,(p+1)%top为边,距离这条边最远的点q,也就是确定了三角形的2个点,找q使得面积最大。
while(Cross(stack[p],stack[(p+1)%top],stack[(q+1)%top])>Cross(stack[p],stack[(p+1)%top],stack[q]))
q=(q+1)%top;
ans=max(ans,Dis2(stack[p],stack[q]));
}
return ans;
}
void Graham(int n)
{
int i,min,top;
point t,stack[50005];
for(i=0,min=0;i<n;i++)
if(v[i].y<v[min].y||(v[i].y==v[min].y&&v[i].x<v[min].x))
min=i;
t=v[0]; v[0]=v[min]; v[min]=t;
sort(v+1,v+n,cmp);
top=-1; stack[++top]=v[0]; stack[++top]=v[1];
for(i=2;i<n;i++)
{
while(top>0&&Cross(stack[top-1],stack[top],v[i])<=0)
top--;
stack[++top]=v[i];
}
printf("%d\n",rotating_calipers(stack,top));
}
int main()
{
int i,n;
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d%d",&v[i].x,&v[i].y);
Graham(n);
return 0;
}