求平面最远点对。
朴素的O(n^2)算法显然超时。这里用到了一种旋转卡壳算法,逆时针开始找,找到第一对对踵点(被一对卡壳正好卡住的对应点),那么以后的点也必然是逆时针排列的。找对踵点可以用一条边找另一点使得该三角形面积最大,之后比较边端点与该点距离即可。
View Code
1 /* 2 Coder:Zhaofa Fang 3 Lang:C++ 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <iostream> 8 #include <cmath> 9 #include <cstring> 10 #include <algorithm> 11 #include <string> 12 #include <vector> 13 #include <queue> 14 #include <stack> 15 #include <map> 16 #include <set> 17 #define pb push_back 18 using namespace std; 19 20 //========================================== 21 const double PI=acos(-1); 22 23 struct Point 24 { 25 double x,y; 26 }point[50005],res[50005]; 27 28 double det(double x1,double y1,double x2,double y2) 29 { 30 return x1*y2-x2*y1; 31 } 32 double xmult(Point o,Point a ,Point b) 33 { 34 return det(a.x-o.x,a.y-o.y,b.x-o.x,b.y-o.y); 35 } 36 double dis(Point a,Point b) 37 { 38 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 39 } 40 int dis1(Point a,Point b) 41 { 42 return (int)((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 43 } 44 bool cmp(const Point &x,const Point &y) 45 { 46 if(xmult(point[0],x,y)==0) 47 return dis(point[0],x)<dis(point[0],y); 48 return xmult(point[0],x,y)>0; 49 } 50 int Graham(int n) 51 { 52 Point tmp; 53 int k=0,top=2; 54 for(int i=1;i<n;i++) 55 { 56 if(point[i].y<point[k].y || point[i].y==point[k].y && point[i].x<point[k].x) 57 k=i; 58 } 59 tmp=point[0],point[0]=point[k],point[k]=tmp; 60 sort(point+1,point+n,cmp); 61 res[0]=point[0],res[1]=point[1],res[2]=point[2]; 62 for(int i=3;i<n;i++) 63 { 64 while(top && xmult(res[top-1],res[top],point[i])<=0)top--; 65 res[++top]=point[i]; 66 } 67 return top+1; 68 } 69 int rotating(int n) 70 { 71 int q=1; 72 int ans=0; 73 res[n]=res[0]; 74 for(int p=0;p<n;p++) 75 { 76 while(fabs(xmult(res[q+1],res[p+1],res[p])) > fabs(xmult(res[q],res[p+1],res[p]))) 77 q=(q+1)%n; 78 ans=max(ans,max(dis1(res[p],res[q]),dis1(res[p+1],res[q]))); 79 } 80 return ans; 81 } 82 int main() 83 { 84 int n; 85 while(~scanf("%d",&n)) 86 { 87 for(int i=0;i<n;i++) 88 { 89 scanf("%lf%lf",&point[i].x,&point[i].y); 90 } 91 int mount=Graham(n); 92 printf("%d\n",rotating(mount)); 93 } 94 return 0; 95 }