很久以前的凸包模版题,又被翻了出来验证旋转卡壳法。。求凸包后枚举2点求距离也可以的。
//Memory: 548K
//Time: 110MS
#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 50001
int top;
int max(int a,int b)
{
return a>b?a:b;
}
struct point
{
int x;
int y;
}p[N],stack[N];
int dist(point p1,point p2)
{
return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
int multiply(point p1,point p2,point p0)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
int cmp(point a,point b)
{
if(multiply(a,b,p[0])>0)
return 1;
if(multiply(a,b,p[0])==0 && dist(a,p[0])<dist(b,p[0]))
return 1;
return 0;
}
void graham(point p[],point stack[],int n) //求凸包
{
int i,k=0;
top=2;
point temp;
for(i=1;i<n;i++)
if(p[i].y<p[k].y || ((p[i].y==p[k].y) && (p[i].x<p[k].x)))
k=i;
temp=p[k];
p[k]=p[0];
p[0]=temp;
sort(p+1,p+n,cmp);
stack[0]=p[0];
stack[1]=p[1];
stack[2]=p[2];
for(i=3;i<n;i++)
{
while(top>1 && multiply( p[i],stack[top],stack[top-1] )>=0 )
top--;
stack[++top]=p[i];
}
stack[++top]=p[0];
}
int rotating_calipers() //旋转卡壳求凸包直径
{
int q=1;
int ans=0;
for(int p=0;p<top;p++)
{
while(multiply(stack[p+1],stack[q+1],stack[p]) > multiply(stack[p+1], stack[q], stack[p]))
q=(q+1)%top;
ans=max(ans, max(dist(stack[p], stack[q]), dist(stack[p+1], stack[q+1])));
}
return ans;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF)
{
int i;
int ans=0;
for(i=0;i<n;i++)
{
scanf("%d%d", &p[i].x, &p[i].y);
}
graham(p,stack,n);
ans=rotating_calipers();
printf("%d\n",ans);
}
}