题目大意:
当一根长度为L的细杆受热后(假设温度提高了n度)它的长度会膨胀到(1 + nC)L,C为热膨胀系数,当此杆固定在竖直的两面墙之间被加热后,它会膨胀成一条圆弧,而原来的直杆所在的位置将称为其弦,而现在就需要求出杆中点位移的距离。
现有多个测例,每个测例都包含杆的原长、温度增量以及热膨胀系数(以三个-1表示测例的结束),对于每个测例都求出杆中点位移的距离(四舍五入精确到3位)。
注释代码:
/*
* Problem ID : POJ 3273 Monthly Expense
* Author : Lirx.t.Una
* Language : C
* Run Time : 0 ms
* Run Memory : 164 KB
*/
#include <stdio.h>
#include <math.h>
#define ESP 1E-4
int
main() {
//设弧长为s、半径为r、棍子的原长为l,位移为h
//由勾股定理已经圆弧角度公式得:
//(l/2)^2 + (r-h)^2 = r^2
//r*sin(s/2r) = l/2
//整理后得到:
//s = 2r*asin(l/2r)
//r = (l^2 + 4h^2) / (8h)
//有图中显而易见的是s(h) = s在图所示的范围是单调递增的
//即随着h的增大弧s的长度显然是增大的
//而又热膨胀关系可以直接算出s = (1+tc)*l
//其中t为温度变化量,c为热膨胀系数
//因此可以在h的一定区间内对其进行二分逼近得到最终答案
//因为题中告诉膨胀不超过l的二分之一,因此s最大为(3/2)*l
//如果使用放缩法以s中点将两边拉直得到一个等腰三角形则可由勾股定理
//得到h不超过sqrt(5)/2倍的l,因此h的区间可以大致确定为[0, 0.5l]
double l, t, c, s, r;
double lft, rht, mid;//h的二分逼近区间
while ( scanf("%lf%lf%lf", &l, &t, &c), l != -1 ) {
if ( t < ESP ) {//温度为0则不膨胀
puts("0.000");
continue;
}
lft = 0.0;
rht = 0.5 * l;
s = ( 1.0 + t * c ) * l;
while ( rht - lft > ESP ) {
mid = ( lft + rht ) / 2.0;
r = ( 4.0 * mid * mid + l * l ) / ( 8.0 * mid );
if ( 2.0 * r * asin( l / ( 2.0 * r ) ) < s )
lft = mid;
else
rht = mid;
}
printf("%.3lf\n", mid);
}
return 0;
}
无注释代码:
#include <stdio.h>
#include <math.h>
#define ESP 1E-4
int
main() {
double l, t, c, s, r;
double lft, rht, mid;
while ( scanf("%lf%lf%lf", &l, &t, &c), l != -1 ) {
if ( t < ESP ) {
puts("0.000");
continue;
}
lft = 0.0;
rht = 0.5 * l;
s = ( 1.0 + t * c ) * l;
while ( rht - lft > ESP ) {
mid = ( lft + rht ) / 2.0;
r = ( 4.0 * mid * mid + l * l ) / ( 8.0 * mid );
if ( 2.0 * r * asin( l / ( 2.0 * r ) ) < s )
lft = mid;
else
rht = mid;
}
printf("%.3lf\n", mid);
}
return 0;
}
单词解释:
rod:n, 棍棒
thin:adj, 薄的,瘦的
heat:vt, 加热; n, 高温,热火
expand:vt, 扩张,膨胀(物理上的)
expanding:adj, 扩张的,膨胀的
expansion:n, 膨胀
coefficient:n, 系数(数学)
mount:vt, 安置,嵌入,挂载
solid:adj, 可靠的,结实的,固体的
take the shape of:呈...形状
circular:adj, 圆形的,循环的
segment:n, 段
chord:n, 弦
displace:vt, 位移,转移,置换
millimeter:n, 毫米
material:n, 材料