POJ 1113(计算几何初步——凸包加圆周长)

这题主要注意几点:

1.共线的处理,我会在代码中注释。

2.PI的精度。

3.极角排序。

View Code
 1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<queue>
5 #include<vector>
6 #include<map>
7 #include<set>
8 #include<cmath>
9 #include<complex>
10 #include<algorithm>
11 #define EPS 1e-10
12 #define largty(x,y) (x-EPS)>(y)
13 #define smalty(x,y) (x+EPS)<(y)
14 #define nlargty(x,y) (x-EPS)<(y)
15 #define nsmalty(x,y) (x+EPS)>(y)
16 #define equal(x,y) (nlargty(x,y) && (nsmalt(x,y)))
17 #define max(a,b) (a)>(b)?(a):(b)
18 #define min(a,b) (a)<(b)?(a):(b)
19 #define PI 3.141592653589793
20 #define MAXN 1010
21 using namespace std;
22 int n;
23 double l;
24 struct point {
25 double x, y;
26 }castle[MAXN],convex[MAXN];
27
28 point start;
29
30 double p_distance(point &p, point &q)
31 {
32 return sqrt(pow(q.x - p.x,2) + pow(q.y - p.y,2));
33 }
34
35 double cross(const point &p1, const point &p2, const point &q1, const point &q2)
36 {
37 return (q2.y - q1.y)*(p2.x - p1.x) - (q2.x - q1.x)*(p2.y - p1.y);
38 }
39
40 bool cmp1(const point &p, const point &q)//选择Y-X排序下最小的点
41 {
42 return p.y < q.y || (p.y == q.y && p.x < q.x);
43 }
44
45 bool cmp2(const point &a, const point &b)//逆时针排序,极角相同则距离短的排前面
46 {
47 point origin;
48 origin = start;
49 return cross(origin,a,origin,b) > 0 || (cross(origin,a,origin,b) == 0 && fabs(a.x) < fabs(b.x));
50 }
51
52 void convex_hull(int &cnt)
53 {
54 sort(castle,castle+n,cmp1);
55 start = castle[0];
56 sort(castle+1,castle+n,cmp2);
57 convex[cnt++] = start;
58 convex[cnt++] = castle[1];
59 for (int i(2); i<n; ++i) {
60 while (cnt >= 2 && cross(convex[cnt-2],convex[cnt-1],convex[cnt-1],castle[i]) <= 0)--cnt;//共线的话也应该弹出原来栈中的点
61 convex[cnt++] = castle[i];
62 }
63 }
64
65 double get_circum(int cnt)
66 {
67 double circum = 0;
68 for (int i(0); i<cnt; ++i) {
69 circum += p_distance(convex[i],convex[(i+1)%cnt]);
70 }
71 circum += 2*PI*l;
72 return circum;
73 }
74
75 int main()
76 {
77 while (scanf("%d%lf",&n,&l) != EOF) {
78 for (int i(0); i<n; ++i) {
79 scanf("%lf%lf",&castle[i].x,&castle[i].y);
80 }
81 int cnt = 0;
82 convex_hull(cnt);
83 printf("%.0lf\n",get_circum(cnt));
84 }
85 return 0;
86 }



转载于:https://www.cnblogs.com/devtang/archive/2012/02/02/2336038.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值