凸包入门(Graham扫描法)(A - Wall POJ - 1113)

题目链接:https://cn.vjudge.net/contest/276359#problem/A

题目大意:有一个国王,要在自己的城堡周围建立围墙,要求围墙能把城堡全部围起来,并且围墙距离城堡的距离至少为l,然后问你最小的消耗量。

具体思路: 将围起来城堡的围墙全部往外移,求出这些点构成的凸包,然后再加上半径为l的圆的周长,这就是最终答案。

AC代码:

 1 #include<iostream>
 2 #include<stack>
 3 #include<iomanip>
 4 #include<string>
 5 #include<stdio.h>
 6 #include<cstring>
 7 #include<iomanip>
 8 #include<cmath>
 9 #include<algorithm>
10 using namespace std;
11 # define ll long long
12 const int maxn = 1e3+100;
13 const double pi= acos(-1.0);
14 struct node
15 {
16     double x,y;
17 } p[maxn],P[maxn];
18 int n,tot;
19 double ans,l;
20 double X(node A,node B,node C)//求叉积的过程
21 {
22     return (B.x-A.x)*(C.y-A.y)-(C.x-A.x)*(B.y-A.y);
23 }
24 double len(node A,node B)
25 {
26     return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
27 }
28 bool cmp(node A,node B)
29 {
30     double pp=X(p[0],A,B);
31     if(pp>0)
32         return true;
33     if(pp<0)
34         return false;
35     return len(p[0],A)<len(p[0],B);
36 }
37 int main()
38 {
39     while(~scanf("%d %lf",&n,&l))
40     {
41         ans=2.0*pi*l;
42         for(int i=0; i<n; i++)
43         {
44             scanf("%lf %lf",&p[i].x,&p[i].y);
45         }
46         if(n==1)
47         {
48             printf("%.0lf\n",ans);
49         }
50         else if(n==2)
51         {
52             printf("%.0lf\n",ans+=len(p[0],p[1]));
53         }
54         else
55         {
56             for(int i=0; i<n; i++)
57             {
58                 if(p[i].y<p[0].y)
59                 {
60                     swap(p[i],p[0]);
61                 }
62                 else if(p[i].y==p[0].y&&p[i].x<p[0].x)
63                 {
64                     swap(p[i],p[0]);
65                 }
66             }//先把第一个点找出来
67             sort(p+1,p+n,cmp);
68             P[0]=p[0];
69             P[1]=p[1];//寻找凸包的起点和终点
70             tot=1;
71             for(int i=2; i<n; i++)
72             {
73                 while(tot>0&&X(P[tot-1],P[tot],p[i])<=0)//斜率相同的时候,取较远的。
74                     tot--;
75                 tot++;
76                 P[tot]=p[i];
77             }
78             for(int i=0; i<tot; i++)
79             {
80                 ans+=len(P[i],P[i+1]);
81             }
82             ans+=len(P[0],P[tot]);
83             printf("%.0lf\n",ans);
84         }
85     }
86     return 0;
87 }
88  

 

posted @ 2018-12-27 18:15  Let_Life_Stop  阅读(220)  评论(0编辑  收藏  举报