盒子
盒子
文章目录
  1. 题目
  2. 题意
  3. 思路
  4. 代码
  5. 更新日志

HDU 5060 War(计算几何)

题目

源地址:http://acm.hdu.edu.cn/showproblem.php?pid=5060

题意

有一个球A:x^2+y^2+z^2 <= r^2 以及一个圆柱体B:x^2+y^2 <= hr^2 且 |z|<=hz
定义VC为两者相交的体积,VU为两者的体积并。求VC/VU

思路

球冠体积:一个球被一个截面所截,其中截面距离球心的距离l。则球冠体积为:πhh*(r-h/3) 其中h=r-l

这道题先求出VC,然后VU=A+B-VC。VC的求法有5种情况

  1. hr >= r && hz >= r (球在圆柱体内)
  2. hr >= r && hz < r (球被圆柱体的两个底面分别截去一个球冠)
  3. hr < r && hr hr + hz hz <= r * r (圆柱体在球内)
  4. hr < r && hz >= r (圆柱体的圆半径小于球半径,但是圆柱体的长度大于球的长度)
  5. (圆柱体的圆半径小于球半径,但是圆柱体的长度小于球的长度)

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#define pb push_back
#define PI cos(-1.0)
#define debug puts("=====================");
using namespace std;
double r, hr, hz;
double vc, vu;
double s(double l) {
double h = r - l;
return PI * h * h * (r - h / 3);
}
int main () {
while(~scanf("%lf%lf%lf", &r, &hr, &hz)) {
double sq = 4.0 / 3 * PI * r * r * r;
double sz = PI * hr * hr * 2 * hz;
if (hr >= r && hz >= r) {
vc = sq;
vu = sz;
}
else if (hr >= r && hz < r) {
vc = sq - 2 * s(hz);
vu = sz + sq - vc;
}
else if (hr < r && hr * hr + hz * hz <= r * r) {
vc = sz;
vu = sq;
}
else if (hr < r && hz >= r) {
double hz1 = sqrt(r * r - hr * hr);
vc = PI * hr * hr * 2 * hz1 + 2 * s(hz1);
vu = sz + sq - vc;
} else {
double hz1 = sqrt(r * r - hr * hr);
vc = PI * hr * hr * 2 * hz1 + 2 * s(hz1) - 2 * s(hz);
vu = sz + sq - vc;
}
printf("%.6lf\n", vc / vu);
}
return 0;
}

更新日志

  • 14562534 2015-08-18 21:30:17 Accepted 5060 2340MS 1596K 1056 B G++ SIO__Five