苏州做网站品牌公司/怎么做电商卖东西
题目不难,主要靠几何数学。题目大意是原有长度为L的桥,现假设温度升高n 摄氏度,其长度变为L'=(1+n*c)*L,其中c为比例系数。桥长度变长后便会弯曲,求其弯曲后中心与原中心的高度差h.假设半径为r,弧度为a,则有数学公式如下:
1)S=(1+n*c)*L;
2)ar=S/2;
3)(r-h)^2+L^2/4=r^2;
4)sina=(L/2)/r;
可推知:r=(4.0*h^2+L^2)/8.0*h;
S=2*r*arcsin(L/(2*r));
先来推算h的大致范围。h>=0,0为最小值。
再估算h的最大值,题目中已经给出了提示,即max(S)=3/2*L,故我们可以在这里将其估算最大值为L/2。估算成L/2绝非偶然,我们分析一下式子:r=(4*h^2+L^2)/8*h;
其在h属于0——L/2范围内单调递增。且r的范围为L/2——INF(正无穷),而同时另一个式子:S=2*r*arcsin(L/(2*r))在r属于L/2——INF范围内单调递增,由复合函数单调性可知S与h在h属于0——L/2范围内成正比。故这里可以使用二分法求解。而不是像有些博客上直接就用了。没有过程的思考。
思路上面已经分析的很清楚了。接下来就是如何使用二分法求解的问题了。其实本身不难,只是由于是double类型数据。故这里要考虑更多的细节。首先while(left<=right)要改成while(right-left>eps),其中eps=1e-5,当然也可以设置的更小一些。
下面是代码: 164K+0MS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define eps 1e-5 //设置最小距离
int main(){
double L,n,c;
while(scanf("%lf%lf%lf",&L,&n,&c)){
if(L<0 || c<0 || n<0)
break;
double S=(1+n*c)*L; // 计算S
double left=0.0,right=0.5*L,mid; // 注意0.5L其实理论上要大于所求高度h,这里为了处理方便,故设计成0.5*L
while(right-left>eps){ // 若超过最小距离,则说明循环结束,高度值求出即为mid
mid=(left+right)/2.0;
double r=(mid*mid*4.0+L*L)/(8.0*mid);
if(2.0*r*asin(L/(2.0*r))<=S) // 若小于等于S则由函数单调性说明h值偏小
left=mid;
else // h值偏大
right=mid;
}
printf("%.3lf\n",mid); // 保留小数点后3位输出 也可使用 cout << fixed << setprecision(3) << mid << endl;
}
return 0;
}