POJ 2187 Beauty Contest
旋转卡壳求最远点对;
#include<iostream> #include<cmath> using namespace std; int n,k; double dt; typedef struct point { double x,y; point(double xx=0,double yy=0):x(xx),y(yy){} }vector; point p[50010],q[50010]; struct line { vector v; }li,lj; void sort1(point *a,int x,int y,point *t) { int m,u,v,i; if(y-x>1) { m=x+(y-x)/2; u=x,v=m,i=x; sort1(a,x,m,t); sort1(a,m,y,t); while(u<m || v<y) { if(v>=y || (u<m && (a[u].x<a[v].x || (a[u].x==a[v].x && a[u].y<=a[v].y)))) t[i++]=a[u++]; else t[i++]=a[v++]; } for(i=x;i<y;i++) a[i]=t[i]; } } vector operator - (point a,point b) {return vector(a.x-b.x,a.y-b.y);} double cross(vector a,vector b) { return a.x*b.y-a.y*b.x; } int convex(point *a,point *t) { int m=0,i; for(i=0;i<n;i++) { while(m>1 && cross(t[m-1]-t[m-2],a[i]-t[m-2])<=0) m--; t[m++]=a[i]; } k=m; for(i=n-1;i>=0;i--) { while(m>k && cross(t[m-1]-t[m-2],a[i]-t[m-2])<=0) m--; t[m++]=a[i]; } if(n>1) m--; return m; } vector rotate(vector a,double rad) { return vector(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad)); } double dot(vector a,vector b) { return a.x*b.x+a.y*b.y; } double length(vector a) { return sqrt(dot(a,a)); } double angle(vector a,vector b) { return acos(dot(a,b)/length(a)/length(b)); } void f(int m,double &dt) { int i=0,j=k-1; double th1,th2,d; while(i!=k-1 || j!=m) { th1=angle(li.v,q[i+1]-q[i]); th2=angle(lj.v,q[(j+1)%m]-q[j]); if(th1<th2) { li.v=rotate(li.v,th1); lj.v=rotate(lj.v,th1); i++; d=dot(q[j]-q[i],q[j]-q[i]); if(d>dt) dt=d; } else if(th1>th2) { li.v=rotate(li.v,th2); lj.v=rotate(lj.v,th2); j++; d=dot(q[j%m]-q[i],q[j%m]-q[i]); if(d>dt) dt=d; } else { li.v=rotate(li.v,th1); lj.v=rotate(lj.v,th2); d=dot(q[j]-q[i+1],q[j]-q[i+1]); if(d>dt) dt=d; d=dot(q[(j+1)%m]-q[i],q[(j+1)%m]-q[i]); if(d>dt) dt=d; i++;j++; d=dot(q[j%m]-q[i],q[j%m]-q[i]); if(d>dt) dt=d; } } } int main() { int i,m; cin>>n; for(i=0;i<n;i++) cin>>p[i].x>>p[i].y; sort1(p,0,n,q); m=convex(p,q); li.v=vector(0,-1); lj.v=vector(0,1); dt=dot(q[k-1]-q[0],q[k-1]-q[0]); f(m,dt); cout<<(int)dt<<endl; return 0; }