HDU1348 Wall 凸包

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=1348

 

题意:给出一个凸包,求出与凸包距离 L的外圈周长

凸包模板题,练练Andrew算法
求出凸包周长再加上半径为l的圆的周长

 1 #include<bits/stdc++.h>
 2 #define N 1050
 3 using namespace std;
 4 int n,l,m;
 5 const double pi=acos(-1);
 6 struct P{
 7     int x,y;
 8     bool operator < (const P &b)const{
 9         return x==b.x?y<b.y:x<b.x;
10     }
11     P operator - (const P &b)const{
12         return (P){x-b.x,y-b.y};
13     }
14 }a[N],s[N];
15 double dis(P a,P b){
16     return sqrt(1.0*(a.x-b.x)*(a.x-b.x)+1.0*(a.y-b.y)*(a.y-b.y));
17 }
18 int crs(P a,P b){return a.x*b.y-a.y*b.x;}
19 void getbag(){
20     m=0;sort(a+1,a+1+n);
21     for(int i=1;i<=n;i++){
22         while(m>1&&crs(a[i]-s[m-1],s[m]-s[m-1])>=0)m--;
23         s[++m]=a[i];
24     }
25     int now=m;
26     for(int i=n-1;i>=1;i--){
27         while(m>now&&crs(a[i]-s[m-1],s[m]-s[m-1])>=0)m--;
28         s[++m]=a[i];
29     }
30     if(n>1)m--;
31 }
32 
33 int main(){
34     int cas;scanf("%d",&cas);
35     while(cas--){
36         scanf("%d%d",&n,&l);
37         for(int i=1;i<=n;i++)
38         scanf("%d%d",&a[i].x,&a[i].y);
39         getbag();
40         double ans=0;
41         for(int i=1;i<m;i++)
42         ans+=dis(s[i],s[i+1]);
43         ans+=dis(s[1],s[m]);
44         ans+=2*pi*l;
45         printf("%.0lf\n",ans);
46         if(cas)puts("");
47     }
48     return 0;
49 }

 

posted @ 2018-01-04 10:10  _wsy  阅读(138)  评论(0)    收藏  举报