给你三个值,L.n,C,;L表示棍子的原长,n,C都代表系数,且该棍子受热后,会产生弯曲,弯曲后的棍子的长度为L' = (1+n*C)*L,现在要你求弯曲的幅度(弯曲幅度不会超过原来的一半)。
解题思路:
设圆心角为rad,半径为r,所以r = L/(2sin(rad)),r = (L'/(2rad));所以可以得到表达式 L/(2sin(rad))= (L'/(2rad)) ,且rad∈[0,PI].求解,注意精度问题
开始时1e-8不过 , 调到1e-12次就过了
原题地址:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=494&page=show_problem&problem=1609
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#define eps 1e-12
#define PI acos(-1.0)
double A,C,B;
int dcmp(double x){
if(fabs(x)<eps){
return 0;
}
return x<0?-1:1;
}
double f(double x){
return B*sin(x) - x*A;
}
double solve(){
double tmp0 = B-PI*A/2;
int flag = dcmp(tmp0);
double Mid,MidVal;
if(flag<0){
double L = acos(A/B);
if(dcmp(L)==0){
L+=eps;
}
double R = PI/2+eps;
while(dcmp(R-L)==1){
Mid = L + (R-L)/2;
MidVal = f(Mid);
if(dcmp(MidVal)>0)L = Mid;
else R = Mid;
}
double r = B/(2*L);
return r - r*cos(L);
}
else if(flag==0){
return A/2;
}
else {
return B/2;
}
}
int main(){
double L,n;
while(scanf("%lf%lf%lf",&L,&n,&C)!=EOF){
if(dcmp(L)<0&&dcmp(n)<0&&dcmp(C)<0)break;
B = (1+n*C)*L;
A = L;
double ans = solve();
printf("%.3f\n",ans);
}
return 0;
}