ICPC Northwestern European Regional Programming Contest B Bottle Flip
题意:
给你一个高度为 H H H ,半径为 r r r的水杯,并告诉你空气密度 ρ a \rho_{a} ρa和水的密度 ρ w \rho_{w} ρw,求使得整个杯子装水后质心最低的水量
大致思路:
前置物理知识:如果处理多个部分的重心比较困难,但整体处理比较简单时,我们可以将求出这一部分物体的质心和质量,这两部分在处理整个物体的质心时时等价的。
即若把物体分成
a
,
b
a,b
a,b两个部分有:
X
=
∑
i
=
0
k
x
i
m
i
∑
i
=
1
k
m
i
X
a
=
∑
i
=
1
k
a
x
i
m
i
∑
i
=
1
k
a
m
i
X
b
=
∑
i
=
1
k
b
x
i
m
i
∑
i
=
1
k
b
m
i
M
a
=
∑
i
=
1
k
a
m
i
M
b
=
∑
i
=
1
k
b
m
i
X
=
X
a
M
a
+
X
b
M
b
M
a
+
M
b
X=\frac{\sum_{i=0}^k x_{i}m_{i}}{\sum_{i=1}^k m_{i}}\\ X_{a}={{\sum_{i=1}^{k_a} x_i m_i}\over \sum_{i=1}^{k_a} m_i}\\ X_{b}={{\sum_{i=1}^{k_b} x_i m_i}\over \sum_{i=1}^{k_b} m_i}\\ M_a=\sum_{i=1}^{k_a} m_i\\ M_b=\sum_{i=1}^{k_b} m_i\\ X={X_aM_a+X_bM_b\over M_a+M_b}
X=∑i=1kmi∑i=0kximiXa=∑i=1kami∑i=1kaximiXb=∑i=1kbmi∑i=1kbximiMa=i=1∑kamiMb=i=1∑kbmiX=Ma+MbXaMa+XbMb
我们设水的高度为
h
h
h,那么重心高度则有
X
w
(
h
)
=
h
2
X
a
(
h
)
=
H
+
h
2
M
a
(
h
)
=
S
(
H
−
h
)
ρ
a
M
w
(
h
)
=
S
h
ρ
w
X
(
h
)
=
1
2
(
S
h
2
ρ
w
+
(
H
2
−
h
2
)
ρ
a
)
S
(
H
−
h
)
ρ
a
+
S
h
ρ
w
=
1
2
(
h
2
ρ
w
+
(
H
2
−
h
2
)
ρ
a
)
(
H
−
h
)
ρ
a
+
h
ρ
w
X_w(h)= {h\over 2}\\ X_a(h)={H+h \over 2}\\ M_a(h)= S(H-h)\rho_a\\ M_w(h)=Sh\rho_w\\ X(h)=\frac{{1 \over 2} (Sh^2 \rho_w+(H^2-h^2) \rho_a)}{S(H-h)\rho_a+Sh\rho_w}= {1 \over 2}\frac{ (h^2 \rho_w+(H^2-h^2) \rho_a)}{(H-h)\rho_a+h\rho_w}
Xw(h)=2hXa(h)=2H+hMa(h)=S(H−h)ρaMw(h)=ShρwX(h)=S(H−h)ρa+Shρw21(Sh2ρw+(H2−h2)ρa)=21(H−h)ρa+hρw(h2ρw+(H2−h2)ρa)
数学较好的同学可以将
X
(
h
)
X(h)
X(h) 对
h
h
h 求导。
另外,我们可以发现 X ( h ) X(h) X(h) 是一个单峰函数,故三分可以通过本题
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long int
double H, y, Pa, Pw;
double eps = 1e-10;
double check(double h)
{
double a1 = (h * h * Pw + (H * H - h * h) * Pa) * 0.5;
double w = h * Pw + (H - h) * Pa;
return a1 / w;
}
signed main()
{
cin >> H >> y >> Pa >> Pw;
double l = 0, r = H;
while (r - l >= eps)
{
double midl, midr;
midl = l + (r - l) / 3;
midr = r - (r - l) / 3;
if (check(midl) > check(midr))
l = midl;
else
r = midr;
}
cout << fixed << setprecision(10) << l << endl;
return 0;
}