题面
分析
如图:已知AB=L,弧AB=L(1+nC)” role=”presentation” style=”position: relative;”>AB=L,弧AB=L(1+nC)AB=L,弧AB=L(1+nC),M为AB中点,N为圆上一点,且ON垂直于AB于M,求MN
设半径为R” role=”presentation” style=”position: relative;”>RR,∠AOM=θ” role=”presentation” style=”position: relative;”>∠AOM=θ∠AOM=θ(弧度),MN=x” role=”presentation” style=”position: relative;”>MN=xMN=x
则可列出方程组
{2Rθ=L(1+nc)(1)Rsinθ=L2(2)x=R(1−cosθ)(3)” role=”presentation” style=”position: relative;”>⎧⎩⎨⎪⎪⎪⎪2Rθ=L(1+nc)(1)Rsinθ=L2(2)x=R(1−cosθ)(3){2Rθ=L(1+nc)(1)Rsinθ=L2(2)x=R(1−cosθ)(3)
若求出θ” role=”presentation” style=”position: relative;”>θθ便可以求出x,所以我们从 θ” role=”presentation” style=”position: relative;”>θθ入手,尝试解上面的方程组
由(1)(2)式得 θsinθ=1+nC” role=”presentation” style=”position: relative;”>θsinθ=1+nCθsinθ=1+nC
本人数学不好,求不出上面的方程的解析解(如果有解析解可以在评论中指出)
于是采用二分的方法来近似求根
显然0<θ≤π2″ role=”presentation” style=”position: relative;”>0<θ≤π20<θ≤π2
由图知θ” role=”presentation” style=”position: relative;”>θθ越大,1+nC越大” role=”presentation” style=”position: relative;”>1+nC越大1+nC越大
我们二分θ” role=”presentation” style=”position: relative;”>θθ,设二分中点为mid,端点为[L,R]并计算midsinmid” role=”presentation” style=”position: relative;”>midsinmidmidsinmid,若midsinmid>1+nC” role=”presentation” style=”position: relative;”>midsinmid>1+nCmidsinmid>1+nC,则寻找更小的,R=mid.否则寻找更大的,L=mid
还有几个细节:
1.π” role=”presentation” style=”position: relative;”>ππ一定要很精确,否则会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)));
}
}