链接:http://poj.org/problem?id=1905
有个L长的棒子,加热变成L‘长。因为卡在两堵墙之间,所以棒子会弯,求弯出来的高度。
加热公式:L’=(1+n*c)*L;
n是加热度数,c是加热系数。
就是求问号的那个高度。
画了个图,方便表达下面的公式。
求X。
几个集合关系式。
r^2=L^2/4+(r-x)^2
L'/2=θ*r
sin(θ)=sin(L'/2*r)=L/(2^r);
得到:
1)r=(L^2+4*x^2)/(8*x)
2)L’=2*r*arcsin(L/2*r)
所以,对x进行二分,
先求1)式中的r,然后带入2)式,检验L‘与右边等式的值,再对low和high进行修改。详见代码吧。
这个题,自己一开始做的时候,先求r时直接根据那个等式来用二分求了,然后再带入下面的式子求x。显然,先用二分求的r是估计值,
然后带入下面会产生更大的误差,所以会wa。然后又想想,这样做貌似方法也不对。还是上面的做法比较好。
#include<cstdio>
#include<cmath>
int cal(double r,double el,double l)
{
if(el<2*r*asin(l/(2*r)))
return 1;
return 0;
}
int main()
{
double l,n,c,el;
double r,low,high,mid;
while(scanf("%lf%lf%lf",&l,&n,&c)!=EOF)
{
if(l<0&&n<0&&c<0)
return 0;
el=(1+n*c)*l;
high=0.5*l;
low=0;
mid=0;
while(fabs(high-low)>1e-6)//控制精度
{
mid=(high+low)/2;
r=(l*l+4*mid*mid)/(8*mid);
if(cal(r,el,l))
high=mid;
else
low=mid;
}
printf("%.3lf\n",mid);
}
return 0;
}