【闲话】
今天是 第 届第 轮考试的后 天,突然发现好多本地的改革都撞上我们这一届了,我们什么运气……
【正题】
【来源】: 清华集训
,一本通
,
【题目大意】: 相比起Wildleopard
家,他弟弟Mildeopard
比较穷。他(弟弟)的房子是狭窄的,而且只有一盏灯,他发现他影子的长度随他在灯泡和墙壁间走动而变化。求影子长度的最大值。
【输入格式】:
第
行
个数
,表示组数。
第
到
行,每行三个数,
,含义如上
【输出格式】:
行,每行一个数
,含义如上
【样例】:
输入: 输出:
3 1.000
2 1 0.5 0.750
2 0.5 3 4.000
4 3 4
【思路】:
首先这题的长度是一个单峰函数,所以可以用三分法解决,问题变成了给定一个数
,求Mildeopard
在位置
时影子长度
。
首先求光线的函数解析式,已知光线经过
和
,分别是灯泡的位置和Mildeopard
头顶的位置,那么根据
可求出
,所以光线和地面的交点的
坐标即为
。
当
时,影子长度即为
,否则即影子在墙上的高度为
,光线经过点
,所以
,影子长度即为
。
【代码】:
int test_number;
double H,h,D;
double lmid,rmid,l,r;
const double eps=1e-5;
inline double f(double mid){
if (mid==0.0) return 0.0;
register double L=(H*mid/(H-h));
if (L<D) return L-mid;
return D-mid+D*(h-H)/mid+H;
}
int main(){
freopen("t1.in","r",stdin);
scanf("%d",&test_number);
while (test_number--){
scanf("%lf%lf%lf",&H,&h,&D);
l=0;r=D;
while (r-l>eps){
lmid=l+(r-l)/3.0;
rmid=r-(r-l)/3.0;
if (f(lmid)<f(rmid)) l=lmid;
else r=rmid;
}
printf("%.3lf\n",f(l));
}
return 0;
}
【小结】: 数学学得好, 也受益!!!