poj 1113 Wall (凸包:周长)

题意:

一个城墙 有n 个点描述, 国王想建一个周长最短的墙,使墙的任意一点到城墙的距离都 > L。求这面墙的周长。

题解":

 最短周长 = 凸包周长  + 半径为 l 的圆的周长。

 还要注意的是这道题 不能 将共线点去掉

  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  1010
 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 int stack[maxn];
 26 int dblcmp(double x)
 27 {
 28     if(fabs(x) < eps) return 0;
 29     if(x < 0return -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 == 0return ;stack[top++] = 0;
 54     if(n == 1return ;stack[top++] = 1;
 55 
 56     for(i = 2 ;i<n;i++)//求右链
 57     {
 58         while(top&&dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) > 0) top--;
 59 
 60         stack[top++] = i;
 61     }
 62 
 63      //dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) 可以直接是 cross
 64     len =  top ;
 65 
 66     for(i = n - 2;i >= 0;i--)//求左链
 67     {
 68          while(top != len && dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) > 0)top--;
 69          stack[top++] = i;
 70 
 71     }
 72     top--;//第一个点入栈两次 所以 减 1
 73 
 74 }
 75 double dis(point a,point b)
 76 {
 77   double x1 = a.x;
 78   double y1 = a.y;
 79   double x2 = b.x;
 80   double y2 = b.y;
 81   return sqrt((x1 - x2)*(x1 - x2)+ (y1 - y2)*(y1 - y2));
 82 }
 83 int main()
 84 {
 85 
 86 
 87       int  i,s,j;
 88     //freopen("data.txt","r",stdin);
 89      int  l;
 90      while(scanf("%d%d",&n,&l)!=EOF)
 91      {
 92          for(i = 0;i < n;i++)
 93          {
 94              scanf("%lf%lf",&p[i].x,&p[i].y);
 95          }
 96          graham();
 97          double ans  = 0 ;
 98 
 99          for(i = 0 ;i < top;i++)
100          {
101              ans += dis(p[stack[i]],p[stack[i + 1]]);
102          }
103 
104          ans+=2*pi*l;
105          printf("%.lf\n",ans);
106      }
107 
108 }
原文地址:https://www.cnblogs.com/acSzz/p/2660227.html