1246:膨胀的木棍
【题目描述】 当长度为L的一根细木棍的温度升高n度,它会膨胀到新的长度L’=(1+n*C)*L,其中C是热膨胀系数。 当一根细木棍被嵌在两堵墙之间被加热,它将膨胀形成弓形的弧,而这个弓形的弦恰好是未加热前木棍的原始位置。 你的任务是计算木棍中心的偏移距离。 【输入】 三个非负实数:木棍初始长度(单位:毫米),温度变化(单位:度),以及材料的热膨胀系数。 保证木棍不会膨胀到超过原始长度的1.5倍。 【输出】 木棍中心的偏移距离(单位:毫米),保留到小数点后第三位。 【输入样例】 1000 100 0.0001 【输出样例】 61.329
【分析】
这题初看就一简单的三函数题:己知弧长、弦长,求扇形半径与弦心距的差,怎么还需要编程呢?不信,我解给你看,来吧,干就完了。
解:设弧长为l,弦长为d,半径为r,扇形中心角为a,中心偏移距离为x。由题目可知:d,n,c为已知量。
l=d*(1+n*c) (可算值) l=r*a (1) r*sina=d/2 (2)
(1)(2) 两式相乘可消元r得一关于a的方程:l*sina=a*d/2(我的神啊,这方程能解吗?你们谁有公式可算记得告诉我。)
这个方程就是传说中的超越方程,目前应该没有公式(怒我孤陋寡闻的小本科生不会解)。
继续读题,寻找线索:“保证木棍不会膨胀到超过原始长度的1.5倍”,这是要给我范围?有范围就可以缩小范围啊,这缩小范围二分法最拿手,
哦,这是要我们用二分法求解中心角吧,求出中心角其他的就好说了。这个中心角初始范围定在(0,pi)(pi代表圆周率)
对哦,这个圆周率好像C++没现成的哦。那用个数学公式换下吧:pi=acos(-1)。那余下的就简单了:x=r-r*cos(a/2)。
【见证奇迹】
//1246:膨胀的木棍 #include<iostream> #include<iomanip> #include<cmath> using namespace std; int main(){ double l,d,c,n,r,alf,x; cin>>d>>n>>c; l=d*(1+n*c); //解方程lsing(alf) =alf*d double m=0;n=acos(-1.0)/2; while(n-m>1e-12) { double b=(m+n)/2; if(l*sin(b)>b*d)m=b; else if(l*sin(b)<b*d)n=b; } alf=m; r=l/alf/2; x=r-r*cos(alf); cout<<fixed<<setprecision(3)<<x; return 0; }