模板凸包(Andrew)

Posted xiaobuxie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板凸包(Andrew)相关的知识,希望对你有一定的参考价值。

题目链接:https://vjudge.net/problem/POJ-1113

题目链接:https://vjudge.net/problem/POJ-3348

安德鲁真的巨快无比。

具体看注释

技术图片
 1 /*************************************************************************
 2     > File Name: poj2079.cpp
 3 # File Name: poj2079.cpp
 4 # Author : xiaobuxie
 5 # QQ : 760427180
 6 # Email:760427180@qq.com
 7 # Created Time: 2019年10月12日 星期六 17时55分28秒
 8  ************************************************************************/
 9 
10 #include<iostream>
11 #include<cstdio>
12 #include<map>
13 #include<cmath>
14 #include<cstring>
15 #include<set>
16 #include<queue>
17 #include<vector>
18 #include<algorithm>
19 using namespace std;
20 typedef long long ll;
21 #define inf 0x3f3f3f3f
22 #define pq priority_queue<int,vector<int>,greater<int> >
23 ll gcd(ll a,ll b){
24     if(a<b) return gcd(b,a);
25     return b==0?a:gcd(b,a%b);
26 }
27 
28 const double pi = acos(-1.0);
29 const int N = 5e4+9;
30 struct Point{
31     double x,y;
32     bool operator < (const Point& b)const{
33         return x<b.x || (x==b.x && y<b.y);
34     }
35     Point operator - (const Point& b)const{
36         return (Point){x-b.x,y-b.y};
37     }
38     double operator ^ (const Point& b)const{
39         return x*b.y - b.x*y;
40     }
41 }p[N],ch[N];
42 int n;
43 inline void init(){
44     for(int i =0 ;i<n;++i) scanf("%lf %lf",&p[i].x,&p[i].y);
45 } 
46 double dis(Point a,Point b){
47     return sqrt( (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) );
48 }
49 
50 /*
51 m代表着top,凸包是从0到m-1
52 一开始求下凸包,接下来求上凸包
53 求出来的凸包是逆时针的
54 */
55 inline int Andrew(){
56     sort(p,p+n);
57     int m = 0;
58     for(int i = 0; i < n;++i){
59         while( m>1 && ((p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2])) >=0) --m;
60         ch[m++] = p[i];
61     }
62     int k = m;
63     for(int i = n-2;i >= 0;--i){
64         while( m>k && ((p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2])) >=0) --m;
65         ch[m++] = p[i];
66     }
67     if(n>1) --m;
68     return m;
69 }
70 int main(){
71     while(~scanf("%d",&n)){
72         int L;
73         scanf("%d",&L);
74         init();
75         int m = Andrew();
76         ch[m] = ch[0];
77         double ans = 0;
78         for(int i = 0;i < m;++i) ans += dis(ch[i],ch[i+1]);
79         ans += 2*pi*L;
80         printf("%d
",(int)(ans+0.5));
81     }
82     return 0;
83 }
View Code
技术图片
 1 /*************************************************************************
 2     > File Name: poj2079.cpp
 3 # File Name: poj2079.cpp
 4 # Author : xiaobuxie
 5 # QQ : 760427180
 6 # Email:760427180@qq.com
 7 # Created Time: 2019年10月12日 星期六 17时55分28秒
 8  ************************************************************************/
 9 
10 #include<iostream>
11 #include<cstdio>
12 #include<map>
13 #include<cmath>
14 #include<cstring>
15 #include<set>
16 #include<queue>
17 #include<vector>
18 #include<algorithm>
19 using namespace std;
20 typedef long long ll;
21 #define inf 0x3f3f3f3f
22 #define pq priority_queue<int,vector<int>,greater<int> >
23 ll gcd(ll a,ll b){
24     if(a<b) return gcd(b,a);
25     return b==0?a:gcd(b,a%b);
26 }
27 
28 const double pi = acos(-1.0);
29 const int N = 5e4+9;
30 struct Point{
31     double x,y;
32     bool operator < (const Point& b)const{
33         return x<b.x || (x==b.x && y<b.y);
34     }
35     Point operator - (const Point& b)const{
36         return (Point){x-b.x,y-b.y};
37     }
38     double operator ^ (const Point& b)const{
39         return x*b.y - b.x*y;
40     }
41 }p[N],ch[N];
42 int n;
43 inline void init(){
44     for(int i =0 ;i<n;++i) scanf("%lf %lf",&p[i].x,&p[i].y);
45 } 
46 /*
47 m代表着top,凸包是从0到m-1
48 一开始求下凸包,接下来求上凸包
49 求出来的凸包是逆时针的
50 */
51 inline int Andrew(){
52     sort(p,p+n);
53     int m = 0;
54     for(int i = 0; i < n;++i){
55         while( m>1 && ((p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2])) >=0) --m;
56         ch[m++] = p[i];
57     }
58     int k = m;
59     for(int i = n-2;i >= 0;--i){
60         while( m>k && ((p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2])) >=0) --m;
61         ch[m++] = p[i];
62     }
63     if(n>1) --m;
64     return m;
65 }
66 int main(){
67     while(~scanf("%d",&n)){
68         init();
69         if(n<3){
70             puts("0");
71             continue;
72         }
73         int m = Andrew();
74         double ans = 0;
75         for(int i = 1;i < m-1;++i) ans += ((ch[i]-ch[0]) ^ (ch[i+1]-ch[0]));
76         ans /= 2;
77         printf("%d
",(int)(ans/50.0));
78     }
79     return 0;
80 }
View Code

 

以上是关于模板凸包(Andrew)的主要内容,如果未能解决你的问题,请参考以下文章

poj1113--凸包(Andrew)

[模板] 计算几何2: 自适应Simpson/凸包/半平面交/旋转卡壳/闵可夫斯基和

LeetCode 812. 最大三角形面积(再次用到凸包的Andrew算法) / 面试题 04.06. 后继者 / 953. 验证外星语词典

Luogu 2742 二维凸包

POJ3528 HDU3662 三维凸包模板

P2742 [USACO5.1]圈奶牛Fencing the Cows /模板二维凸包(计算几何)(凸包)