
Convex Fence
I have a land consisting of n trees. Since the trees are favorites to cows, I have a big problem saving them. So, I have planned to make a fence around the trees. I want the fence to be convex (curves are allowed) and the minimum distance from any tree to the fence is at least d units. And definitely I want a single big fence that covers all trees.
You are given all the information of the trees, to be specific, the land is shown as a 2D plane and the trees are plotted as 2D points. You have to find the perimeter of the fence that I need to create as described above. And you have to minimize the perimeter.
One tree, a circular fence is needed Two trees, the fence is shown
Input starts with an integer T (≤ 10), denoting the number of test cases.
Each case starts with a line containing two integers n (1 ≤ n ≤ 50000), d (1 ≤ d ≤ 1000). Each of the next lines contains two integers xi yi (-108 ≤ xi, yi ≤ 108) denoting a position of a tree. You can assume that all the positions are distinct.
Output
For each case, print the case number and the minimum possible perimeter of the fence. Errors less than 10-3 will be ignored.
Sample Input
3
1 2
0 0
2 1
0 -1
0 2
3 5
0 0
5 0
0 5
Sample Output
Case 1: 12.566370614
Case 2: 12.2831853
Case 3: 48.4869943478
Hint
Dataset is huge, use faster i/o methods.
题目就是说,给定几个点,要用围栏围住所有点,且围栏与每个点的距离不小于D.
样例太水,再举几个例子:
多画几个图,你很快就会发现,所求答案就是原图凸包的周长+以D为半径的园的周长,水一水就过了.
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #define LL long long #define PI (acos(-1.0)) using namespace std; int n,top; double R; ],ch[]; point operator - (point u,point v){point ret; ret.x=u.x-v.x,ret.y=u.y-v.y; return ret;} double dis(point u,point v){return sqrt((u.x-v.x)*(u.x-v.x)+(u.y-v.y)*(u.y-v.y));} LL cross(point u,point v){return u.x*v.y-v.x*u.y;} inline int read(){ ,f=; char ch=getchar(); '){if (ch=='-') f=-f; ch=getchar();} +ch-',ch=getchar(); return x*f; } bool cmp(const point &u,const point &v){ ],v-a[])>||cross(u-a[],v-a[])==&&dis(u,a[])<dis(v,a[]); } void Out_(){ ; ){ ; i<top; i++) ans+=dis(ch[i],ch[i+]); ans+=dis(ch[top],ch[]); } ans+=PI*R*; printf("%.7lf\n",ans); } void Graham(){ ; ; i<=n; i++) if (a[i].y<a[now].y||a[i].y==a[now].y&&a[i].x<a[now].x) now=i; swap(a[now],a[]); sort(a+,a++n,cmp); ch[]=a[],ch[]=a[],ch[]=a[],top=; ; i<=n; i++){ ],ch[top]-ch[top-])>) top--; ch[++top]=a[i]; } } int main(){ ; Ts<=T; Ts++){ scanf(,,sizeof ch); ; i<=n; i++) a[i].x=read(),a[i].y=read(); printf("Case %d: ",Ts); Graham(),Out_(); } ; }