Description
有一个圆形的水池,水池的圆心坐标为(0, 0)。有座桥跨越水池,桥可以看作直线段AB,A点和B点都在水池边上。
Merlin想从F点走到G点,并且F点和G点都在水池边上,但是他不会游泳。请告诉他从F点到G点的最短路程是多少。
Input
输入有多组数据。
每组数据的第一行是一个整数R (1<=R<=100), 表示水池的半径。
第二行包含8个实数XA, YA, XB, YB, XF, YF, XG, YG, 分别表示A,B,F,G点的坐标。每组坐标满足|X2+Y2-R2| < 10-8。
Output
每组数据输出一行,输出答案四舍五入到两位小数。
Sample Input
1
0.729627 -0.683845334 0.198022 -0.9801975758 0.314911 -0.9491212052 -0.735596 -0.6774204933
1
0.517308 0.8557992949 0.936038 -0.351898938 0.396901 -0.9178614254 0.616543 -0.7873212363
Sample Output
1.15
0.26
Data Constraint
数据范围
对于所有数据,1<=R<=100,|X2+Y2-R2| < 10-8。
赛时
旁边一位大佬说是三角函数,然后他就a了,于是我也无视这道题。
正解
上网查三角函数找公式,(还看了看别人的博客):
别人的:
两点间的弦长(设为d):d=根号下[(x2-x1)²+(y2-y1)²]
圆心角θ=2arcsin(d/2r)
弧长L=rθ=2r·arcsin(d/2r
AB距离为sqrt((XA-XB)(XA-XB)+(YA-YB)(YA-YB));
代码
#include<bits/stdc++.h>
#define PI 3.1415926
using namespace std;
int r;
double xa,ya,xb,yb,xf,yf,xg,yg,fg,ab,abfg;
double min(double a, double b){return a<b?a:b;}
double hu(double x1,double y1,double x2,double y2,double r){
double xc,yxj1,yxj2,h1,h2;
xc=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
yxj1=asin(xc/(2*r))*2,yxj2=PI*2-yxj1;
h1=r*yxj1,h2=r*yxj2;
return min(h1,h2);
}
int main(){
freopen("pool.in","r",stdin);
freopen("pool.out","w",stdout);
while(scanf("%d",&r)!=EOF){
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&xa,&ya,&xb,&yb,&xf,&yf,&xg,&yg);
fg=hu(xf,yf,xg,yg,r);
ab=sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));
abfg=min(hu(xa,ya,xf,yf,r),hu(xb,yb,xf,yf,r))+min(hu(xb,yb,xg,yg,r),hu(xa,ya,xg,yg,r));
printf("%.2lf\n",min(fg,ab+abfg));
}
}

探讨了在圆形水池中,如何计算两点间最短路径的问题,利用三角函数和几何原理,给出了具体的算法实现。
656

被折叠的 条评论
为什么被折叠?



