您的位置:首页 > 其它

poj 2187 Beauty Contest (凸包: 最远点对,最长直径 , 旋转卡壳法)

2012-08-28 17:04 288 查看
http://poj.org/problem?id=2187

题意:

最长的点对近距离的平方:

题解:

旋转卡壳法, 要注意的地方是,有 所有点共线的情况,所以,(求凸包时)要将,共线点去出 ;

1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define maxn 50100
15 #define eps 1e-12
16 #define inf 100000000
17 #define mx 1<<60
18 #define ll __int64
19 const double pi = acos(-1.0);
20 using namespace std;
21 struct point
22 {
23 double x,y;
24 }p[maxn];
25 point stack[maxn];
26 int dblcmp(double x)
27 {
28 if(fabs(x) < eps) return 0;
29 if(x < 0) return -1;
30 else return 1;
31 }
32 double det(double x1,double y1,double x2,double y2)
33 {
34 return x1*y2 - x2*y1 ;
35 }
36 double cross(point a, point b, point c)
37 {
38 return det(b.x - a.x, b.y - a.y, c.x - a.x, c.y - a.y);
39 }
40 int cmp(point a,point b)
41 {
42 if(a.y != b.y) return a.y < b.y;
43 else return a.x < b.x;
44 }
45 int top ,n;
46 void graham()
47 {
48
49 int i,len;
50 top = 0;
51 sort(p,p+n,cmp);
52
53 if(n == 0) return ;
54 if(n == 1) return ;
55 stack[top++] = p[0];
56 stack[top++] = p[1];
57 for(i = 2 ;i<n;i++)//求右链
58 {
59 while(top > 1&& cross(stack[top - 1],stack[top - 2],p[i]) >= 0) top--;
60
61 stack[top++] = p[i];
62 }
63
64 //dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) 可以直接是 cross
65 len = top ;
66
67 for(i = n - 2;i >= 0;i--)//求左链
68 {
69 while(top > len && cross(stack[top - 1],stack[top - 2],p[i]) >= 0)top--;
70 stack[top++] = p[i];
71
72 }
73 top--;//第一个点入栈两次 所以 减 1
74
75 }
76 double dis(point a,point b)
77 {
78 double x1 = a.x;
79 double y1 = a.y;
80 double x2 = b.x;
81 double y2 = b.y;
82 return (x1 - x2)*(x1 - x2)+ (y1 - y2)*(y1 - y2);
83 }
84 double rotating_calipers(point stack[],int top)
85 {
86 int i;
87 int q = 1;
88 double ans = 0;
89 stack[top] = stack[0] ;
90
91
92 for(i = 0;i < top;i++ )
93 {
94 while(cross(stack[i+1],stack[q+1],stack[i]) > cross(stack[i + 1],stack[q],stack[i]))
95 q = (q+1)%top;
96
97
98
99 ans = max(ans,max(dis(stack[i],stack[q]),dis(stack[i+1],stack[q+1])));

}
return ans ;
}
int main()
{

int i,s,j;
//freopen("data.txt","r",stdin);
while(scanf("%d",&n)!=EOF)
{
for(i = 0;i< n;i++)
{
scanf("%lf%lf",&p[i].x,&p[i].y);
}
graham() ;

double ans = rotating_calipers(stack,top);
printf("%.0lf\n",ans);

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: