P6988
考虑对每个平行于圆柱底面的截面,记其到圆柱底面的距离为
我们以截面上圆柱轴与截面的交点为原点,截面上过原点且平行于底面的直线为
对于水面与截面交线在坐标系中的高度
不妨考虑其与底面的高度
对于所截得圆的半径
-
-
否则求出
x 超出的部分的长度x'=-x 或x-l (根据在左侧或者右侧),然后不难得到:
然后大力积分就做完了。
const ff EPS = 1e-8, INF = 1e5, PI = acos(-1);
ff d, l, r, t, h;
ff Sq(ff x) { return x * x; }
ff F(ff x) {
ff l_d = sqrt(Sq(l) - Sq(t)) + EPS;
ff Y = (h * l - t * x) / l_d - d / 2, R = 0;
if(x > -EPS && x < l + EPS) R = d / 2;
else {
R = Sq(r) - Sq(sqrt(Sq(r) - Sq(d / 2)) + (x < EPS ? -x : x - l));
if(R < 0) return 0;
R = sqrt(R);
}
ff s_cir = Sq(R) * PI;
if(Y > R - EPS) return s_cir;
if(Y < -R + EPS) return 0;
ff s = sqrt(Sq(R) - Sq(Y)) * Y,
s_arc = acos(Y / R) * Sq(R);
return s_cir - s_arc + s;
}
ff Simp(ff L, ff R) {
return (R - L) * (F(L) + 4 * F((L + R) / 2) + F(R)) / 6;
}
ff Asr(ff L, ff R, ff ans, int step) {
ff mid = (L + R) / 2, fl = Simp(L, mid), fr = Simp(mid, R);
if(fabs(fl + fr - ans) < EPS && step < 0) return (fl + fr + ans) / 2;
return Asr(L, mid, fl, step - 1) + Asr(mid, R, fr, step - 1);
}
ff Solve(ff L, ff R) {
return Asr(L, R, Simp(L, R), 12);
}
int main() {
rd(d, l, r, t, h);
d /= 100; l /= 100; r /= 100; t /= 100; h /= 100;
printf("%.2lf\n", Solve(-r, l + r));
return 0;
}