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);
}
}
题意:
最长的点对近距离的平方:
题解:
旋转卡壳法, 要注意的地方是,有 所有点共线的情况,所以,(求凸包时)要将,共线点去出 ;
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);
}
}
相关文章推荐
- uvalive 4728(旋转卡壳求凸包最长直径)
- 【凸包直径&平面最远点对&对锺点(旋转卡壳)】poj 2187 Beauty Contest
- poj 2187 Beauty Contest , 旋转卡壳求凸包的直径的平方
- poj 2187 凸包上的直径 - 旋转卡壳
- 求平面集内距离最长 (凸包+旋转卡壳)
- 【POJ 2187】Beauty Contest(凸包直径、旋转卡壳)
- 计算凸包直径—旋转卡壳算法
- POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
- POJ 2187 Beauty Contest【旋转卡壳求凸包直径】
- 旋转卡壳--求凸包最大直径
- LA 4728凸包算法-旋转卡壳的直径
- UVALive 4728 Squares(旋转卡壳求凸包直径)
- POJ 2187 求多边形直径(凸包+旋转卡壳)
- 旋转卡壳--凸包的直径
- POJ 2187 旋转卡壳求凸包的直径
- LA 4728 旋转卡壳算法求凸包的最大直径
- POJ 2187 Beauty Contest(旋转卡壳求点凸包直径)
- POJ2187Beauty Contes【凸包Graham+旋转卡壳求凸包直径+排除共线】
- 旋转卡壳--求凸包最大直径
- UVa 1453 - Squares 旋转卡壳求凸包直径