题意
有一个灯泡高度为
H
H
H,它与墙壁的距离为
D
D
D,
Mildleopard
\text{Mildleopard}
Mildleopard 站在灯泡与墙壁之间,身高为
h
h
h,他与灯光所构成的影长为
L
L
L,问你
L
L
L 的最大长度为多少?
思路
我们设 Mildleopard \text{Mildleopard} Mildleopard 与灯泡的位置为 x x x,将影长设为 y y y,求出 x x x 和 y y y 的函数解析式即可求出最值从而求出本题的解。我们考虑分类讨论来得出此问题的答案。
当影子不在墙壁上时
我们很容易就能看出
△
A
B
C
∼
△
P
Q
C
\triangle ABC\sim \triangle PQC
△ABC∼△PQC,根据定理,可以得到
A
B
P
Q
=
B
C
Q
C
\displaystyle\frac{AB}{PQ}=\frac{BC}{QC}
PQAB=QCBC
再将式子中的线段替换成我们已知的变量,即
H
h
=
x
+
y
y
\displaystyle\frac{H}{h}=\frac{x+y}{y}
hH=yx+y
然后将其化简
H
y
=
h
(
x
+
y
)
Hy=h(x+y)
Hy=h(x+y)
H
y
=
h
x
+
h
y
Hy=hx+hy
Hy=hx+hy
(
H
−
h
)
y
=
h
x
(H-h)y=hx
(H−h)y=hx
可得出函数解析式,即为
y
=
h
H
−
h
x
y=\frac{h}{H-h}x
y=H−hhx
但是还需要考虑函数的定义域,因为我们需要保证影子不在墙上,所以
x
+
y
x+y
x+y 最多也就只能取到
D
D
D,即
x
+
y
≤
D
x+y\le D
x+y≤D
可将
Y
Y
Y 带入,再化简,又得
x
+
h
H
−
h
x
≤
D
x+\frac{h}{H-h}x\le D
x+H−hhx≤D
H
H
−
h
x
≤
D
\frac{H}{H-h}x\le D
H−hHx≤D
x
≤
D
H
−
h
H
x\le D\frac{H-h}{H}
x≤DHH−h
则当前情况函数解析式为
y
=
h
H
−
h
x
(
0
≤
x
≤
D
H
−
h
H
)
y=\frac{h}{H-h}x(0\le x \le D\frac{H-h}{H})
y=H−hhx(0≤x≤DHH−h)
当影子有一部分再墙上时
我们将
y
y
y 分成了两段,分别是
y
1
y_{1}
y1 和
y
2
y_{2}
y2,我们要求的
y
y
y 即为它们的和。
显而易见, y 2 y_{2} y2 等于 D − x D-x D−x,所以现在只需要算出 y 1 y_{1} y1 也就是 N M NM NM 的长度即可。
在此图中,我们仍可以构建出一个相似三角形, △ A B C ∼ △ P Q C \triangle ABC\sim \triangle PQC △ABC∼△PQC,发现此组相似三角形与上一种情况完全相等,可以根据上一情况,得出 C Q = h H − h x \displaystyle CQ=\frac{h}{H-h}x CQ=H−hhx(下列式子中将用 t t t 来代替 h H − h \displaystyle\frac{h}{H-h} H−hh)
我们还可以发现,可以再构建出一组相似三角形
△
P
Q
C
∼
△
N
M
C
\triangle PQC\sim \triangle NMC
△PQC∼△NMC,又可得到
P
Q
N
M
=
Q
C
M
C
\displaystyle\frac{PQ}{NM}=\frac{QC}{MC}
NMPQ=MCQC,再将所有我们已知的变量带入,进行替换,可以得到:
h
y
1
=
s
x
s
x
−
y
2
\frac{h}{y_{1}}=\frac{sx}{sx-y_{2}}
y1h=sx−y2sx
又因
y
2
y_{2}
y2 我们已经得出,可直接替换
h
y
1
=
s
x
s
x
−
D
+
x
\frac{h}{y_{1}}=\frac{sx}{sx-D+x}
y1h=sx−D+xsx
h
y
1
=
s
x
x
(
s
+
1
)
−
D
\frac{h}{y_{1}}=\frac{sx}{x(s+1)-D}
y1h=x(s+1)−Dsx
h
[
x
(
s
+
1
)
−
D
]
=
s
x
×
y
1
h[x(s+1)-D]=sx\times y_{1}
h[x(s+1)−D]=sx×y1
y
2
=
h
[
x
(
s
+
1
)
−
D
]
s
x
y_{2}=\frac{h[x(s+1)-D]}{sx}
y2=sxh[x(s+1)−D]
y
2
=
h
×
[
x
(
s
+
1
)
s
x
−
D
s
x
]
y_{2}=h\times[\frac{x(s+1)}{sx}-\frac{D}{sx}]
y2=h×[sxx(s+1)−sxD]
y
2
=
h
×
(
s
+
1
s
−
D
s
x
)
y_{2}=h\times(\frac{s+1}{s}-\frac{D}{sx})
y2=h×(ss+1−sxD)
这时,我们可以再将
h
H
−
h
\displaystyle\frac{h}{H-h}
H−hh 替换回来,即
y
2
=
h
×
(
h
H
−
h
+
1
h
H
−
h
−
D
h
H
−
h
x
)
y_{2}=h\times(\frac{\frac{h}{H-h}+1}{\frac{h}{H-h}}-\frac{D}{\frac{h}{H-h}x})
y2=h×(H−hhH−hh+1−H−hhxD)
y
2
=
h
×
(
H
H
−
h
h
H
−
h
−
D
h
H
−
h
x
)
y_{2}=h\times(\frac{\frac{H}{H-h}}{\frac{h}{H-h}}-\frac{D}{\frac{h}{H-h}x})
y2=h×(H−hhH−hH−H−hhxD)
y
2
=
h
×
(
H
h
−
D
(
H
−
h
)
h
x
)
y_{2}=h\times(\frac{H}{h}-\frac{D(H-h)}{hx})
y2=h×(hH−hxD(H−h))
y
2
=
H
−
D
(
H
−
h
)
x
y_{2}=H-\frac{D(H-h)}{x}
y2=H−xD(H−h)
因为我们求的是
y
1
y_{1}
y1 和
y
2
y_{2}
y2 的和,所以需要再加上一个
y
1
y_{1}
y1。并且不要忘记加定义域,人离灯泡最远的情况就是已经贴在墙上了,所以上限取到
D
D
D,下线就是比上一个函数定义域的上限多即可。所以第二种方案的函数解析式即为
y
=
D
−
x
+
H
−
D
(
H
−
h
)
x
(
D
H
−
h
H
≤
x
≤
D
)
y=D-x+H-\frac{D(H-h)}{x}(D\frac{H-h}{H}\le x\le D)
y=D−x+H−xD(H−h)(DHH−h≤x≤D)
再将两者结合,构成一个分段函数
y
=
{
h
H
−
h
x
(
0
≤
x
≤
D
H
−
h
H
)
D
−
x
+
H
−
D
(
H
−
h
)
x
(
D
H
−
h
H
≤
x
≤
D
)
y=\begin{cases} \displaystyle\frac{h}{H-h}x(0\le x \le D\frac{H-h}{H}) \\\displaystyle D-x+H-\frac{D(H-h)}{x}(D\frac{H-h}{H}\le x\le D) \end{cases}
y=⎩
⎨
⎧H−hhx(0≤x≤DHH−h)D−x+H−xD(H−h)(DHH−h≤x≤D)
然后就是取最大值。
取最大值的思路十分明确,取两段分段函数的值,然后再取最大即可。
先看第一个,它是一个正比例函数且单调递增,那么取最大值时,
x
x
x 就应该取
D
H
−
h
H
\displaystyle D\frac{H-h}{H}
DHH−h,那最大值即为
y
m
a
x
=
h
H
−
h
×
D
H
−
h
H
=
D
h
H
y_{max}=\frac{h}{H-h}\times D\frac{H-h}{H}=\frac{Dh}{H}
ymax=H−hh×DHH−h=HDh
第二个函数的话我们可以先将其移一下项,可得
y
=
D
+
H
−
[
x
+
D
(
H
−
h
)
x
]
y=D+H-[x+\frac{D(H-h)}{x}]
y=D+H−[x+xD(H−h)]
可以发现,中括号内的式子为一个对勾函数。如果我们要让 y y y 更大,就要让这个对勾函数取最小值。
那要怎么来取呢?这里用均值不等式来简单证一下。
将其套入基本不等式,可得
x
+
D
(
H
−
h
)
x
≥
2
x
D
(
H
−
h
)
x
x+\frac{D(H-h)}{x}\ge 2\sqrt {x\frac{D(H-h)}{x}}
x+xD(H−h)≥2xxD(H−h)
x
+
D
(
H
−
h
)
x
≥
2
D
(
H
−
h
)
x+\frac{D(H-h)}{x}\ge 2\sqrt {D(H-h)}
x+xD(H−h)≥2D(H−h)
当且仅当 x = D ( H − h ) x \displaystyle x=\frac{D(H-h)}{x} x=xD(H−h) 时,等号成立。所以最大值即为 D + H − 2 D ( H − h ) D+H-2\sqrt {D(H-h)} D+H−2D(H−h),再取两式最大即可。
可这样的话您会 WA \text{WA} WA 的很惨
因为是当且仅当
x
=
D
(
H
−
h
)
x
\displaystyle x=\frac{D(H-h)}{x}
x=xD(H−h) 时,等号成立,可以取到最大值,但要是如果
D
(
H
−
h
)
x
\displaystyle\frac{D(H-h)}{x}
xD(H−h) 不在
x
x
x 的取值范围内该怎么办呢?凉拌
我们先将此等式化简一下
x
2
=
D
(
H
−
h
)
\displaystyle x^{2}=D(H-h)
x2=D(H−h)
x
=
D
(
H
−
h
)
x=\sqrt{D(H-h)}
x=D(H−h)
然后,我们再进行分类讨论。
- 如果 D ( H − h ) ∈ [ D H − h H , D ] \displaystyle\sqrt{D(H-h)}\in[D\frac{H-h}{H},D] D(H−h)∈[DHH−h,D],那么皆大欢喜, D ( H − h ) \sqrt{D(H-h)} D(H−h) 在 x x x 能取到的范围之内,直接取 D + H − 2 D ( H − h ) D+H-2\sqrt {D(H-h)} D+H−2D(H−h)
- 如果 D ( H − h ) ∈ [ D , ∞ + ) \displaystyle\sqrt{D(H-h)}\in[D,\infty ^{+}) D(H−h)∈[D,∞+),说明 x x x 的取值范围在最值 D ( H − h ) \sqrt{D(H-h)} D(H−h) 的左边,因为目前对勾函数左边单调递增,所以 x x x 如果要取最大,一定要取到它的取值范围的右端点,即 y m a x = D + H − [ D + D ( H − h ) D ] = h \displaystyle y_{max}=D+H-[D+\frac{D(H-h)}{D}]=h ymax=D+H−[D+DD(H−h)]=h
- 如果 D ( H − h ) ∈ [ ∞ − , D H − h H ) \displaystyle\sqrt{D(H-h)}\in[\infty ^{-},D\frac{H-h}{H}) D(H−h)∈[∞−,DHH−h),说明 x x x 的取值范围在最值 D ( H − h ) \sqrt{D(H-h)} D(H−h) 的右边,因为目前对勾函数右边单调递减,所以 x x x 如果要取最大,一定要取到它的取值范围的做端点,即 y m a x = D + H − [ D H − h H + D ( H − h ) D H − h H ] = D h H \displaystyle y_{max}=D+H-[D\frac{H-h}{H}+\frac{D(H-h)}{D\frac{H-h}{H}}]=\frac{Dh}{H} ymax=D+H−[DHH−h+DHH−hD(H−h)]=HDh
将其合并成一个分段函数即为
y
m
a
x
=
{
D
h
H
(
D
(
H
−
h
)
≤
D
H
−
h
H
)
D
+
H
−
2
D
(
H
−
h
)
(
D
H
−
h
H
≤
D
(
H
−
h
)
≤
D
)
h
(
D
≤
D
(
H
−
h
)
)
y_{max}=\begin{cases}\displaystyle\frac{Dh}{H}(\sqrt{D(H-h)}\le D\frac{H-h}{H}) \\\displaystyle D+H-2\sqrt {D(H-h)}(D\frac{H-h}{H}\le\sqrt{D(H-h)}\le D) \\\displaystyle h(D\le \sqrt{D(H-h)}) \end{cases}
ymax=⎩
⎨
⎧HDh(D(H−h)≤DHH−h)D+H−2D(H−h)(DHH−h≤D(H−h)≤D)h(D≤D(H−h))
哪个符合条件就选哪个,最后取两段函数最大值的最大值即可
代码不是很难,按照题目推出来的公式直接照搬即可
#include<bits/stdc++.h>
using namespace std;
double max(double a,double b){return a>b?a:b;}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
double H,h,D;
scanf("%lf %lf %lf",&H,&h,&D);
double ans1,ans2;
ans1=D*h/H;
if(sqrt(D*(H-h))<=D*((H-h)/H))
ans2=D*h/H;
if(D*((H-h)/H)<=sqrt(D*(H-h))&&sqrt(D*(H-h))<=D)
ans2=D+H-2*sqrt(D*(H-h));
if(D<=sqrt(D*(H-h))) ans2=h;
printf("%.3lf\n",max(ans1,ans2));
}
return 0;
}