先求出实际弧长(也就是受热膨胀后的竹竿长度),然后二分各种 h,求出 h 对应的弧长,如果弧长小于实际弧长,那么证明该 h 偏小,否则 h 偏大。具体还有几个细节请看代码。
1 #include
2 #include
3 using namespace std;
4 const double PI=acos(-1.0);
5 int main(){
6 double L,n,C;
7 while(scanf("%lf%lf%lf",&L,&n,&C)==3&&(L>=0&&n>=0&&C>=0)){
8 double nL=(1.0+n*C)*L; //nL--实际弧长
9 double l=0.0,r=0.5*L;
10 while(r-l>1e-8){
11 double mid=(l+r)/2;
12 double Rs=L*L/(8.0*mid)+mid/2; //Rs--mid对应的弧的半径
13 double thata=asin(L/(2*Rs)); //弧角的一半。这里其实还有一种求法:acos((Rs-mid)/Rs),但如果用这种求法可能就WA了,想来可能是Rs这个有误差的值在此出现了2次(另一种求法之出现了1次),被卡精度了。以后做计算几何的时候要注意这个问题:在运算过程中尽量少用存在精度问题的数据!
14 double LL=Rs*2.0*thata; //弧长公式
15 if(LLmid;
16 else r=mid;
17 }
18 printf("%.3f\n",(l+r)/2); //这里有个巨坑!要是写"%.3lf\n"就WA,屡试不爽!无解。
19 }
20 return 0;
21 }