题面
分析
如图:已知
AB=L,弧AB=L(1+nC)
A
B
=
L
,
弧
A
B
=
L
(
1
+
n
C
)
,M为AB中点,N为圆上一点,且ON垂直于AB于M,求MN
设半径为
R
R
,(弧度),
MN=x
M
N
=
x
则可列出方程组
⎧⎩⎨⎪⎪⎪⎪2Rθ=L(1+nc)(1)Rsinθ=L2(2)x=R(1−cosθ)(3)
{
2
R
θ
=
L
(
1
+
n
c
)
(
1
)
R
sin
θ
=
L
2
(
2
)
x
=
R
(
1
−
cos
θ
)
(
3
)
若求出
θ
θ
便可以求出x,所以我们从
θ
θ
入手,尝试解上面的方程组
由(1)(2)式得
θsinθ=1+nC
θ
sin
θ
=
1
+
n
C
本人数学不好,求不出上面的方程的解析解(如果有解析解可以在评论中指出)
于是采用二分的方法来近似求根
显然
0<θ≤π2
0
<
θ
≤
π
2
由图知
θ
θ
越大,
1+nC越大
1
+
n
C
越
大
我们二分
θ
θ
,设二分中点为mid,端点为[L,R]并计算
midsinmid
m
i
d
sin
m
i
d
,若
midsinmid>1+nC
m
i
d
sin
m
i
d
>
1
+
n
C
,则寻找更小的,R=mid.否则寻找更大的,L=mid
还有几个细节:
1.
π
π
一定要很精确,否则会WA
2.设定的二分误差要尽量小
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define eps 1e-11
#define pi 3.141592653589793
using namespace std;
double L,n,C,theta,x;
int main(){
while(scanf("%lf %lf %lf",&L,&n,&C)!=EOF){
if(L==n&&n==C&&C==-1) break;
if(n*C==0){
printf("0.000\n");
continue;
}
double l=eps,r=pi/2;//用弧度表示角
while(fabs(l-r)>eps){
double mid=(l+r)/2;
double hu=mid/sin(mid);
if(hu>1+n*C) r=mid;
else l=mid;
}
theta=l;
double R=L/(2*sin(theta));
printf("%.3f\n",R*(1-cos(theta)));
}
}