题目链接
http://poj.org/problem?id=2187
题目大意
求平面上最远的两个点的距离的平方。
思路
裸凸包+旋转卡壳求凸包上最远点对。。。
注意旋转卡壳的很多细节,不然会WA。。。
其实这个题也是可以用
O(n2)
暴力水过的,因为数据太弱。。。
代码
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <cmath>
#define MAXN 51000
#define EPS 1e-6
using namespace std;
int n;
int dcmp(double x)
{
if(fabs(x)<EPS) return 0;
if(x>EPS) return 1;
return -1;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y):x(_x),y(_y){}
}points[MAXN],stack[MAXN];
Point operator-(Point a,Point b)
{
return Point(a.x-b.x,a.y-b.y);
}
double operator*(Point a,Point b)
{
return a.x*b.x+a.y*b.y;
}
double dist(Point a,Point b)
{
return ((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
int top=0;
bool cmp(Point a,Point b)
{
if(!dcmp(a.x-b.x)) return a.y<b.y;
return a.x<b.x;
}
double cross(Point a,Point b) //a->b X a->c
{
return a.x*b.y-b.x*a.y;
}
void Graham()
{
sort(points+1,points+n+1,cmp);
for(int i=1;i<=n;i++)
{
while(top>=2&&dcmp(cross(stack[top]-stack[top-1],points[i]-stack[top-1])<=0)) top--; //!!!!
stack[++top]=points[i];
}
int tmp=top;
for(int i=n-1;i>=1;i--)
{
while(top>=tmp+1&&dcmp(cross(stack[top]-stack[top-1],points[i]-stack[top-1])<=0)) top--;
stack[++top]=points[i];
}
}
double rotcalip()
{
double ans=0;
int p=2;
for(int i=1;i<=top;i++)
{
while(dcmp(cross(stack[i+1]-stack[i],stack[p]-stack[i])-cross(stack[i+1]-stack[i],stack[p+1]-stack[i]))<0) p=p%top+1; //!!!!!!我顶你个肺
ans=max(ans,max(dist(stack[p],stack[i]),dist(stack[p],stack[i+1])));
}
return ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&points[i].x,&points[i].y);
Graham();
printf("%d\n",(int)rotcalip());
return 0;
}