题意:已知平面的一些点的坐标,求最远两点的距离的平方值。
分析:这题题意很简单,但如果直接枚举肯定会超时,不过可以转化为求凸包,
因为最远两点肯定为它们的凸包的两个顶点,这样枚举凸包上的点求距离,时间就大大减少了
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct stu
{
int x,y;
}p[50010],s[50010];
int m,top;
int chaji(struct stu p1,struct stu p2,struct stu p3) //叉积
{
return (p1.x-p2.x)*(p3.y-p2.y)-(p3.x-p2.x)*(p1.y-p2.y);
}
double dis(struct stu p1,struct stu p2) //两点的距离的平方
{
return (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);
}
int cmp(struct stu p1,struct stu p2)
{
int k;
k=chaji(p1,p[0],p2);
if(k>0||(k==0&&dis(p1,p[0])<dis(p2,p[0])))
return 1;
return 0;
}
void graham()
{
int i,k=0;
struct stu t;
for(i=1;i<m;i++)
if(p[i].y<p[k].y||(p[i].y==p[k].y&&p[i].x<p[k].x)) //先找到最左下的点作为凸包的第一个顶点
k=i;
t=p[k];
p[k]=p[0];
p[0]=t;
sort(p+1,p+m,cmp); //将除凸包第一个顶点外,按任意两点与第一个顶点的叉积正负排序
s[0]=p[0];
s[1]=p[1];
top=1;
for(i=2;i<m;i++){
while(top>=1&&chaji(s[top-1],s[top],p[i])>=0)
top--;
top++;
s[top]=p[i];
}
}
int main()
{
int n,i,j,k;
while(scanf("%d",&m)!=EOF){
if(m==0)
break;
for(i=0;i<m;i++)
scanf("%d%d",&p[i].x,&p[i].y);
graham(); //用Graham算法求凸包上的点
k=0;
for(i=0;i<=top;i++) //枚举凸包上的点,求最远两点的距离的平方
for(j=0;j<i;j++){
n=dis(s[i],s[j]);
if(n>k)
k=n;
}
printf("%d\n",k);
}
return 0;
}