浏览器标题切换
浏览器标题切换end

POJ1113-Wall-求凸包周长

题意:

国王要把n个城堡外建城墙,使得城墙距离任一城堡的距离都大于L,给出n个城堡的坐标,求城墙的最小周长。

 

思路:

利用城堡的坐标可以形成一个凸包,在拐角处画一个半径为L的圆弧,最终所有圆弧合起来正好是一个半径为L的圆,所以答案就是凸包的周长+半径为L的圆的周长。

先求凸包的顶点,再叉积求面积,两点间的距离公式求周长。

 

注意:

因为结果四舍五入,

处理方法:

输出用%.0f,表示输出浮点数整数部分,省略小数部分;

或者在double后面加上0.5,在最后输出的时候把double类型强制转换成int即可,注意加(int),不要直接%d输出。

 

AC代码:

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<string.h>
 6 
 7 using namespace std;
 8 typedef long long ll;
 9 #define inf 0x3f3f3f3f
10 #define PI acos(-1)
11 const int N=1020;
12 
13 struct node
14 {
15     double x,y;
16 }p[N],st[N];
17 int n;
18 
19 double cross(node a,node b,node c)//计算叉积 ab*ac
20 {
21     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
22 }
23 
24 int cmp(node a,node b)
25 {
26     if(a.x!=b.x)
27         return a.x<b.x;
28     return a.y<b.y;
29 }
30 
31 double dist(node a,node b)
32 {
33     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
34 }
35 
36 int Andrew()
37 {
38     sort(p,p+n,cmp);
39     int x=0;
40     for(int i=0;i<n;i++)
41     {
42         while(x>1&&cross(st[x-2],st[x-1],p[i])<=0)
43             x--;
44         st[x++]=p[i];
45     }
46     int k=x;
47     for(int i=n-2;i>=0;i--)
48     {
49         while(x>k&&cross(st[x-2],st[x-1],p[i])<=0)
50             x--;
51         st[x++]=p[i];
52     }
53     return x-1;
54 }
55 
56 int main()
57 {
58     int L;
59     while(~scanf("%d %d",&n,&L))
60     {
61         memset(st,0,sizeof(st));
62         for(int i=0;i<n;i++)
63             scanf("%lf %lf",&p[i].x,&p[i].y);
64         int x=Andrew();
65         double ans=0;
66         for(int i=0;i<x;i++)
67             ans+=dist(st[i],st[i+1]);
68         ans=ans+dist(st[0],st[x])+2*PI*L+0.5;//+0.5
69         printf("%d\n",(int)ans);//lf
70     }
71     return 0;
72 }
View Code

 

posted @ 2020-04-15 22:28  抓水母的派大星  阅读(142)  评论(0编辑  收藏  举报