农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏。他建造的围栏必须包括他的奶牛喜欢吃草的所有地点。对于给出的这些地点的坐标,计算最短的能够围住这些点的围栏的长度。
输入格式:
输入数据的第一行包括一个整数 N。N(0 <= N <= 10,000)表示农夫约翰想要围住的放牧点的数目。接下来 N 行,每行由两个实数组成,Xi 和 Yi,对应平面上的放牧点坐标(-1,000,000 <= Xi,Yi <= 1,000,000)。数字用小数表示。
输出格式:
输出必须包括一个实数,表示必须的围栏的长度。答案保留两位小数。
输入样例#1:
4
4 8
4 12
5 9.3
7 8
输出样例#1:
12.00
题目翻译来自NOCOW。
USACO Training Section 5.1
计算几何,确实让人恶心。。。
这题就是一个裸的凸包,
用A什么算法求,
注意一下,
需要开double的不要忘了开double!!!!!!!!!!
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #define vec point
7 using namespace std;
8 const double eps=1e-8;
9 const int MAXN=10001;
10 int n;
11 void read(int &n)
12 {
13 char c='+';int x=0;bool flag=0;
14 while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
15 while(c>='0'&&c<='9'){x=x*10+(c-48);c=getchar();}
16 flag==1?n=-x:n=x;
17 }
18 inline int dcmp(double x)
19 {
20 if(fabs(x)<eps) return 0;
21 else return x>0?1:-1;
22 }
23 struct point
24 {
25 double x,y;
26 inline point(double x=0,double y=0):x(x),y(y){};
27 }p[MAXN],ch[MAXN];
28 vec operator - (vec a,vec b) {return vec(a.x-b.x,a.y-b.y);}
29 vec operator + (vec a,vec b) {return vec(a.x+b.x,a.y+b.y);}
30 vec operator == (vec a,vec b){return (dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0);}
31 int comp(const point &a,const point &b)
32 {
33 if(a.x==b.x) return a.y<b.y;
34 else return a.x<b.x;
35 }
36 int stack[MAXN];
37 double cross(vec a,vec b){return a.x*b.y-a.y*b.x;}
38 int convex_hull()
39 {
40 sort(p+1,p+n+1,comp);
41 int top=1;
42 for(int i=1;i<=n;i++)
43 {
44 while(top>2&& dcmp(cross(ch[top-1]-ch[top-2], p[i]-ch[top-2]))<=0) top--;
45 ch[top++]=p[i];
46 }
47 int tmp=top+1;
48 for(int i=n-1;i>=1;i--)
49 {
50 while(top+1>tmp&& dcmp(cross(ch[top-1]-ch[top-2], p[i]-ch[top-2]))<=0) top--;
51 ch[top++]=p[i];
52 }
53 if(n>2) top--;
54 return top;
55 }
56 double dis(point a,point b)
57 {
58 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
59 }
60 int main()
61 {
62 //freopen("fc.in","r",stdin);
63 //freopen("fc.out","w",stdout);
64 read(n);
65 //ios::sync_with_stdio(0);
66 for(int i=1;i<=n;i++)
67 {
68 double a,b;
69 cin>>a>>b;
70 p[i]=point(a,b);
71 }
72 int num=convex_hull();
73 double ans=0.0;
74 for(int i=1;i<num;i++)
75 ans+=dis(ch[i],ch[i+1]);
76 ans+=dis(ch[num],ch[1]);
77 printf("%.2lf",ans);
78 return 0;
79 }