http://poj.org/problem?id=2187
题目大意:给n个点,求点对最大距离的平方。
————————————————————
很容易证明最大距离的点对在最大凸包上。
那么就是旋转卡壳的裸题了。
旋转卡壳要不要写讲解呢……
#include<cstdio> #include<queue> #include<cctype> #include<cstring> #include<stack> #include<cmath> #include<algorithm> using namespace std; const int N=50001; struct point{ int x; int y; }p[N],q[N]; int n,per[N],l; inline point getmag(point a,point b){ point s; s.x=b.x-a.x;s.y=b.y-a.y; return s; } inline int multiX(point a,point b){ return a.x*b.y-b.x*a.y; } inline int dis(point a,point b){ return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y); } inline bool cmp(int u,int v){ int det=multiX(getmag(p[1],p[u]),getmag(p[1],p[v])); if(det!=0)return det>0; return dis(p[1],p[u])<dis(p[1],p[v]); } void graham(){ int id=1; for(int i=2;i<=n;i++){ if(p[i].x<p[id].x||(p[i].x==p[id].x&&p[i].y<p[id].y))id=i; } if(id!=1)swap(p[1],p[id]); for(int i=1;i<=n;i++)per[i]=i; sort(per+2,per+n+1,cmp); q[++l]=p[1]; for(int i=2;i<=n;i++){ int j=per[i]; while(l>=2&&multiX(getmag(q[l-1],p[j]),getmag(q[l-1],q[l]))>=0)l--; q[++l]=p[j]; } return; } inline int area(point a,point b,point c){ return multiX(getmag(a,b),getmag(a,c)); } int calliper(){ if(l==2)return dis(q[1],q[2]); int res=0; for(int i=1,j=3;i<=l;i++){ while(j%l+1!=i&&area(q[i],q[i%l+1],q[j])<=area(q[i],q[i%l+1],q[j%l+1]))j=j%l+1; res=max(res,dis(q[i],q[j])); res=max(res,dis(q[i%l+1],q[j])); } return res; } int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%d%d",&p[i].x,&p[i].y); graham(); printf("%d\n",calliper()); return 0; }