题目链接:
题目大意:给出点集和一个长度L,要求用最短长度的围墙把所有点集围住,并且围墙每一处距离所有点的距离最少为L,求围墙的长度。
解法:凸包+以L为半径的圆的周长。以题目中的图为例,两点之间的围墙长度之和正好就是凸包的长度,再加上每个点的拐角处(注意此处为弧,才能保证城墙距离点的距离最短)的长度。
1 #include2 #include 3 #include 4 #include 5 #include 6 #include 7 #define inf 0x7fffffff 8 #define exp 1e-10 9 #define PI 3.14159265410 using namespace std;11 int n,L;12 struct Point13 {14 double x,y;15 Point (double x=0,double y=0):x(x),y(y){}16 friend bool operator < (Point a,Point b)17 {18 if (a.x!=b.x) return a.x 1 && dcmp(cross(ch[m-1]-ch[m-2],p[i]-ch[m-1]))<=0) m--;42 ch[m++]=p[i];43 }44 int k=m;45 for (int i=n-2 ;i>=0 ;i--)46 {47 while (k>m && dcmp(cross(ch[k-1]-ch[k-2],p[i]-ch[k-1]))<=0) k--;48 ch[k++]=p[i];49 }50 ch[k++]=ch[0];51 if (n>1) k--;52 return k;53 }54 int main()55 {56 while (cin>>n>>L)57 {58 for (int i=0 ;i