1393: Robert Hood 旋转卡壳 凸包
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1393
http://poj.org/problem?id=2187 Beauty Contest
1393: Robert Hood
Description
Input
Output
Sample Input
5
-4 1
-100 0
0 4
2 -3
2 300
Sample Output
316.86590223
HINT
Source
分析:
给你 N 个点, 求所有点中最远两点距离。即是凸包直径。
AC代码:
1 #include<stdio.h> 2 #include<math.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn = 100000+10; 8 int n,m; 9 10 struct Point{ 11 double x,y; 12 Point(){}; 13 Point(double _x, double _y) 14 { 15 x = _x; 16 y = _y; 17 } 18 19 Point operator - (const Point & B) const 20 { 21 return Point(x-B.x, y-B.y); 22 } 23 }p[maxn], ch[maxn]; 24 25 bool cmp(Point p1, Point p2) 26 { 27 if(p1.x == p2.x) return p1.y < p2.y; 28 return p1.x < p2.x; 29 } 30 31 int squarDist(Point A, Point B) /**距离的平方*/ 32 { 33 return (A.x-B.x)*(A.x-B.x) + (A.y-B.y)*(A.y-B.y); 34 } 35 36 double Cross(Point A, Point B) /**叉积*/ 37 { 38 return A.x*B.y-A.y*B.x; 39 } 40 41 void ConvexHull() /** 基于水平的Andrew算法求凸包 */ 42 { 43 sort(p,p+n,cmp); /**先按照 x 从小到大排序, 再按照 y 从小到大排序*/ 44 m = 0; 45 46 for(int i = 0; i < n; i++) /** 从前往后找 */ 47 { 48 while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--; 49 ch[m++] = p[i]; 50 } 51 int k = m; 52 for(int i = n-2; i >= 0; i--) /**从后往前找, 形成完整的封闭背包*/ 53 { 54 while(m > k && Cross(ch[m-1]-ch[m-2], p[i]-ch[m-2]) <= 0) m--; 55 ch[m++] = p[i]; 56 } 57 if(n > 1) m--; 58 } 59 60 int rotating_calipers() /**旋转卡壳模板*/ 61 { 62 int q = 1; 63 int ans = 0; 64 ch[m] = ch[0]; /**凸包边界处理*/ 65 for(int i = 0; i < m; i++) /**依次用叉积找出凸包每一条边对应的最高点*/ 66 { 67 while(Cross(ch[i+1]-ch[i], ch[q+1]-ch[i]) > Cross(ch[i+1]-ch[i], ch[q]-ch[i])) 68 q = (q+1)%m; 69 ans = max(ans, max(squarDist(ch[i], ch[q]), squarDist(ch[i+1], ch[q+1]))); 70 } 71 return ans; 72 } 73 74 int main() 75 { 76 while(scanf("%d", &n) != EOF) 77 { 78 if(n == 0) break; 79 for(int i = 0; i < n; i++) 80 scanf("%lf%lf", &p[i].x, &p[i].y); 81 82 ConvexHull(); 83 84 printf("%.8lf\n", sqrt(rotating_calipers())); 85 } 86 return 0; 87 }
同学用结构体 + 遍历凸包也可以解决。
AC代码:
1 #include<iostream> 2 #include<algorithm> 3 #include<math.h> 4 using namespace std; 5 struct point 6 { 7 int x; 8 int y; 9 }p[100005],res[100005]; 10 int cmp(point p1,point p2) 11 { 12 return p1.y<p2.y||(p1.x==p2.x&&p1.x<p2.x); 13 } 14 bool ral(point p1,point p2,point p3) 15 { 16 return (p2.x-p1.x)*(p3.y-p1.y)>(p3.x-p1.x)*(p2.y-p1.y); 17 } 18 int main() 19 { 20 int n,i,j; 21 while((scanf("%d",&n))!=EOF) 22 { 23 for(i=0;i<n;i++) 24 scanf("%d %d",&p[i].x,&p[i].y); 25 sort(p,p+n,cmp); 26 res[0]=p[0]; 27 res[1]=p[1]; 28 int top=1; 29 for(i=2;i<n;i++) 30 { 31 while(top&&!ral(res[top],res[top-1],p[i])) 32 top--; 33 res[++top]=p[i]; 34 } 35 int len=top; 36 res[++top]=p[n-2]; 37 for(i=n-3;i>=0;i--) 38 { 39 while(top!=len&&!ral(res[top],res[top-1],p[i])) 40 top--; 41 res[++top]=p[i]; 42 } 43 double maxx=0; 44 for(i=0;i<top;i++) 45 { 46 for(j=i+1;j<top;j++) 47 { 48 double s=(res[i].x-res[j].x)*(res[i].x-res[j].x)+(res[i].y-res[j].y)*(res[i].y-res[j].y); 49 if(s>maxx) 50 maxx=s; 51 52 } 53 } 54 printf("%.8lf\n",sqrt(maxx)); 55 } 56 return 0; 57 }
悠游天地间 all rights reserved. © 2013 -- 1 << 64