题目描述
As Jacques-Édouard really likes birthday cakes, he celebrates his birthday every hour, instead of every year. His friends ordered him a round cake from a famous pastry shop, and placed candles on its top surface. The number of candles equals the age of Jacques-Édouard in hours. As a result, there is a huge amount of candles burning on the top of the cake. Jacques-Édouard wants to blow all the candles out in one single breath.
You can think of the flames of the candles as being points in the same plane, all within a disk of radius R (in nanometers) centered at the origin. On that same plane, the air blown by Jacques-Édouard follows a trajectory that can be described by a straight strip of width W, which comprises the area between two parallel lines at distance W, the lines themselves being included in that area. What is the minimum width W such that Jacques-Édouard can blow all the candles out if he chooses the best orientation to blow?
You can think of the flames of the candles as being points in the same plane, all within a disk of radius R (in nanometers) centered at the origin. On that same plane, the air blown by Jacques-Édouard follows a trajectory that can be described by a straight strip of width W, which comprises the area between two parallel lines at distance W, the lines themselves being included in that area. What is the minimum width W such that Jacques-Édouard can blow all the candles out if he chooses the best orientation to blow?
输入
The first line consists of the integers N and R, separated with a space, where N is Jacques-Édouard’s age in hours. Then N lines follow, each of them consisting of the two integer coordinates xi and yi of the ith candle in nanometers, separated with a space.
Limits
Limits
输出
Print the value W as a floating point number. An additive or multiplicative error of 10−5 is tolerated: if y is the answer, any number either within [y − 10−5,y + 10−5] or within [(1 − 10−5)y,(1 + 10−5)y] is accepted.
样例输入
3 10
0 0
10 0
0 10
样例输出
7.0710678118654755
题意:给出n个点,求用线段平移 可以覆盖全部点 的 最短平移长度。
咱也不懂,只是转载
//旋转卡壳算法 ——
#include <iostream> #include <stdio.h> #include <algorithm> #include <cmath> #include <math.h> #include <cstring> #include <string> #include <queue> #include <deque> #include <stack> #include <stdlib.h> #include <list> #include <map> #include <utility> #include <set> #include <bitset> #include <vector> #define pi acos(-1.0) #define inf 0x3f3f3f3f #define linf 0x3f3f3f3f3f3f3f3fLL #define ms(a,b) memset(a,b,sizeof(a)) using namespace std; typedef long long ll; int min3(int a,int b,int c){return min(min(a,b),c);} int max3(int a,int b,int c){return max(max(a,b),c);} int gcd(int x, int y){if(y==0)return x;return gcd(y, x%y);} inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();return x*f;} struct Point { double x, y, dis; }pt[200005], stackk[200005], p0; int top, tot; //计算几何距离 double Dis(double x1, double y1, double x2, double y2) { return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } //极角比较, 返回-1: p0p1在p0p2的右侧,返回0:p0,p1,p2共线 int Cmp_PolarAngel(struct Point p1, struct Point p2, struct Point pb) { double delta=(p1.x-pb.x)*(p2.y-pb.y)-(p2.x-pb.x)*(p1.y-pb.y); if (delta<0.0) return 1; else if (delta==0.0) return 0; else return -1; } // 判断向量p2p3是否对p1p2构成左旋 bool Is_LeftTurn(struct Point p3, struct Point p2, struct Point p1) { int type=Cmp_PolarAngel(p3, p1, p2); if (type<0) return true; return false; } //先按极角排,再按距离由小到大排 int Cmp(const void*p1, const void*p2) { struct Point*a1=(struct Point*)p1; struct Point*a2=(struct Point*)p2; int type=Cmp_PolarAngel(*a1, *a2, p0); if (type<0) return -1; else if (type==0) { if (a1->dis<a2->dis) return -1; else if (a1->dis==a2->dis) return 0; else return 1; } else return 1; } //求凸包 void Hull(int n) { int i, k; p0.x=p0.y=inf; for (i=0;i<n;i++) { scanf("%lf %lf",&pt[i].x, &pt[i].y); if (pt[i].y < p0.y) { p0.y=pt[i].y; p0.x=pt[i].x; k=i; } else if (pt[i].y==p0.y) { if (pt[i].x<p0.x) { p0.x=pt[i].x; k=i; } } } pt[k]=pt[0]; pt[0]=p0; for (i=1;i<n;i++) pt[i].dis=Dis(pt[i].x,pt[i].y, p0.x,p0.y); qsort(pt+1, n-1, sizeof(struct Point), Cmp); //去掉极角相同的点 tot=1; for (i=2;i<n;i++) if (Cmp_PolarAngel(pt[i], pt[i-1], p0)) pt[tot++]=pt[i-1]; pt[tot++]=pt[n-1]; //求凸包 top=1; stackk[0]=pt[0]; stackk[1]=pt[1]; for (i=2;i<tot;i++) { while (top>=1 && Is_LeftTurn(pt[i], stackk[top], stackk[top-1])==false) top--; stackk[++top]=pt[i]; } } //计算叉积 double CrossProduct(struct Point p1, struct Point p2, struct Point p3) { return (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y); } //卡壳旋转,求出凸多边形所有对踵点 double hl(double a,double b,double c) { double p=(a+b+c)/2.0; return sqrt(p*(p-a)*(p-b)*(p-c)); } double dist(Point a,Point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); } void Rotate(struct Point*ch, int n) { int i, p=1; double t1, t2, ans=inf, dif; ch[n]=ch[0]; for (i=0;i<n;i++) { //如果下一个点与当前边构成的三角形的面积更大,则说明此时不构成对踵点 while (fabs(CrossProduct(ch[i],ch[i+1],ch[p+1])) > fabs(CrossProduct(ch[i],ch[i+1],ch[p]))) p=(p+1)%n; dif=fabs(CrossProduct(ch[i],ch[i+1],ch[p+1])) - fabs(CrossProduct(ch[i],ch[i+1],ch[p])); //如果当前点和下一个点分别构成的三角形面积相等,则说明两条边即为平行线,对角线两端都可能是对踵点 t1=hl(dist(ch[i],ch[i+1]),dist(ch[i+1],ch[p]),dist(ch[p],ch[i]))*2.0/dist(ch[i],ch[i+1]); //printf(">>%lf\n",dist(ch[i],ch[i+1])); if (t1<ans)ans=t1; } printf("%.16lf\n",ans); } int main (void) { int n; scanf("%d%*d",&n); Hull(n); Rotate(stackk, top+1); return 0; }