首页 > 代码库 > cogs896 圈奶牛 凸包

cogs896 圈奶牛 凸包

链接:http://cogs.pro/cogs/problem/problem.php?pid=896

题意:给出一些点,求出这些点的凸包。

几何第一题留念……

题意已经很明白了,求出这些点的凸包。题目没有什么可以说的,这里给出两种实现方式,供读者参考。

技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=10010;
 8 int n,s[maxn],top;
 9 struct point
10 {
11     double x,y;
12 }p[maxn];
13 double dis(point a,point b)
14 {
15     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
16 }
17 double operator *(point a,point b)
18 {
19     return a.x*b.y-b.x*a.y;
20 }
21 point operator -(point a,point b)
22 {
23     return (point){a.x-b.x,a.y-b.y};
24 }
25 bool operator <(point a,point b)
26 {
27     double s=(a-p[1])*(b-p[1]);
28     if(!s)return dis(a,p[1])<dis(b,p[1]);
29     return s>0;
30 }
31 void graham()
32 {
33     s[++top]=1;
34     for(int i=2;i<=n;i++)
35     {
36         while(top>1&&(p[s[top]]-p[s[top-1]])*(p[i]-p[s[top]])<0)top--;
37         s[++top]=i;
38     }
39 }
40 int haha()
41 {
42     freopen("fc.in","r",stdin);
43     freopen("fc.out","w",stdout);
44     scanf("%d",&n);int k=1;
45     for(int i=1;i<=n;i++)
46     {
47         scanf("%lf%lf",&p[i].x,&p[i].y);
48         if(p[i].x<p[k].x&&p[i].y<p[k].y)k=i;
49     }
50     swap(p[k],p[1]);sort(p+2,p+n+1);
51     graham();
52     double ans=0;
53     for(int i=2;i<=top;i++)ans+=dis(p[s[i]],p[s[i-1]]);
54     ans+=dis(p[s[top]],p[1]);
55     printf("%0.2lf\n",ans);
56 }
57 int sb=haha();
58 int main(){;}
极角序
技术分享
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int maxn=10010;
 8 const double eps=1e-8;
 9 struct point
10 {
11     double x,y;
12     bool operator<(const point &b)const
13     {
14         return (x==b.x)?(y<b.y):(x<b.x);
15     }
16     friend point operator -(point a,point b)
17     {
18         return (point){a.x-b.x,a.y-b.y};
19     }
20 }p[maxn];
21 int n,s[maxn];
22 #include<vector>
23 vector<point>convex;
24 bool vis[maxn];
25 double dis(point a,point b)
26 {
27     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
28 }
29 double cross(point a,point b)
30 {
31     return a.x*b.y-b.x*a.y;
32 }
33 bool across(point a,point b,point c)
34 {
35     return cross(b-a,c-a)>eps;
36 }
37 double graham()
38 {
39     s[0]=0;double ans=0.0;
40     sort(p+1,p+n+1);
41     s[++s[0]]=1;s[++s[0]]=2;
42     for(int i=3;i<=n;i++)
43     {
44         while(s[0]>1&&!across(p[s[s[0]]],p[i],p[s[s[0]-1]]))s[0]--;
45         s[++s[0]]=i;
46     }
47     for(int i=1;i<=s[0];i++)vis[s[i]]=1,convex.push_back(p[s[i]]);
48     s[0]=0;s[++s[0]]=n;s[++s[0]]=n-1;
49     for(int i=n-2;i;i--)
50     {
51         while(s[0]>1&&across(p[s[s[0]]],p[s[s[0]-1]],p[i]))s[0]--;
52         s[++s[0]]=i;
53     }
54     for(int i=1;i<=s[0];i++)
55         if(!vis[s[i]])convex.push_back(p[s[i]]);
56     for(int i=0,s=convex.size();i<s;i++)ans+=dis(convex[i],convex[(i+1)%s]);
57     return ans;
58 }
59 int haha()
60 {
61     freopen("fc.in","r",stdin);
62     freopen("fc.out","w",stdout);
63     scanf("%d",&n);
64     for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
65     printf("%0.2lf",graham());
66 }
67 int sb=haha();
68 int main(){;}
水平序

cogs896 圈奶牛 凸包