poj 1113 Wall 凸包的应用

题目链接:poj 1113   单调链凸包小结

题解:本题用到的依然是凸包来求,最短的周长,只是多加了一个圆的长度而已,套用模板,就能搞定;

AC代码:

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cmath>
 5 using namespace std;
 6 int m,n;
 7 struct p
 8 {
 9     double x,y;
10     friend int operator <(p a, p b)
11     {
12         if(a.x<b.x || ( a.x==b.x && a.y<b.y))
13             return 1;
14         return 0;
15     }
16 }a[1010],ans[1010];
17 double judge(p a, p b ,p c)
18 {
19     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
20 }
21 int getnumber()//寻找关键点,来求出最短的周长 
22 {
23     int k=0;
24     for(int i=0; i<m; i++)
25     {
26         while(k>1 && judge(ans[k-2],ans[k-1],a[i])<=0)
27         {
28             k--;
29         }
30         ans[k++]=a[i];
31     }
32     int k1=k;
33     for(int i=m-1; i>=0; i--)
34     {
35         while(k>k1 && judge(ans[k-2],ans[k-1],a[i])<=0)
36         {
37             k--;
38         }
39         ans[k++]=a[i];
40     }
41     return k-1;//第一个点存了两次; 
42 }
43 
44 int main()
45 {
46     scanf("%d %d",&m,&n);
47         for(int i=0; i<m; i++)
48             scanf("%lf %lf",&a[i].x,&a[i].y);
49     sort(a,a+m);
50     int top=getnumber();
51     double ans1=0;
52     int i;
53     for( i=0; i<top; i++){
54      ans1+=sqrt((ans[i].x-ans[i+1].x)*(ans[i].x-ans[i+1].x)+(ans[i].y-ans[i+1].y)*(ans[i].y-ans[i+1].y));
55     }
56     //其实最后只需要加上一个圆的周长就ok了,多边形的外角和为360度; 
57     ans1+=2*3.141592653*n;
58     printf("%.0f
",ans1);//G++  这个才能过不能用(.0l%),C++可以 
59   return 0;
60 }


 

原文地址:https://www.cnblogs.com/lovychen/p/3990131.html