题面
分析
如图:已知,M为AB中点,N为圆上一点,且ON垂直于AB于M,求MN
设半径为,(弧度),
则可列出方程组
若求出便可以求出x,所以我们从 入手,尝试解上面的方程组
由(1)(2)式得
本人数学不好,求不出上面的方程的解析解(如果有解析解可以在评论中指出)
于是采用二分的方法来近似求根
显然
由图知越大,
我们二分,设二分中点为mid,端点为[L,R]并计算,若,则寻找更小的,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
");
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
",R*(1-cos(theta)));
}
}