题解 | #Girlfriend#
Arithmetic Progression
https://ac.nowcoder.com/acm/contest/11253/A
F - Girlfriend
题意: 给出四个点以及
,求
点集构成的几何体相交部分的体积
题解:
- 口胡了一下两个几何体是球,事实上也可以用配方法证明是球
- 容易求出两个球的球心和半径
- 然后就是求两个球相交部分的体积了
- 还需判断两个球的位置关系
#include <bits/stdc++.h> using namespace std; #define dbg(x...) do{ cout << #x << " -> "; err(x);} while (0) void err() {cout << endl;} template<class T, class... Ts> void err(const T& arg, const Ts&... args) { cout << arg << " "; err(args...);} typedef long long ll; const int maxn = 1e5 + 7; const double eps = 1e-8; const double pi = acos(-1.0); double k1, k2; int sgn(double x) { if(fabs(x) < eps) return 0; if(x < 0) return -1; return 1; } struct Point{ double x, y, z; Point(double _x = 0, double _y = 0, double _z = 0) { x = _x; y = _y; z = _z; } void input() { scanf("%lf%lf%lf", &x, &y, &z); } Point operator - (const Point &b) const{ return Point(x - b.x, y - b.y, z - b.z); } Point operator + (const Point &b) const{ return Point(x + b.x, y + b.y, z + b.z); } Point operator * (const double &k) const{ return Point(x * k, y * k, z * k); } Point operator / (const double &k) const{ return Point(x / k, y / k, z / k); } double distance(const Point &b) const{ return sqrt((x - b.x) * (x - b.x) + (y - b.y) * (y - b.y) + (z - b.z) * (z - b.z)); } }p[10]; void run() { for(int i = 1; i <= 4; i++) p[i].input(); scanf("%lf%lf", &k1, &k2); Point v1 = p[2] - p[1]; Point a = v1 * (k1 / (k1 + 1)) + p[1]; Point b = v1 / (k1 - 1) + p[2]; Point c1 = (a + b) / 2.0; double r1 = c1.distance(a); Point v2 = p[4] - p[3]; Point c = v2 * (k2 / (k2 + 1)) + p[3]; Point d = v2 / (k2 - 1) + p[4]; Point c2 = (c + d) / 2.0; double r2 = c2.distance(c); // printf("%.3f %.3f %.3f %.3f %.3f %.3f", a.x, a.y, a.z, b.x, b.y, b.z); double dd = c1.distance(c2); double ans = 0; if(sgn(min(r1, r2) + max(r1, r2) - dd) == -1) ans = 0; else if(sgn(max(r1, r2) - dd - min(r1, r2)) == 1) ans = 4.0 / 3.0 * pi * min(r1, r2) * min(r1, r2) * min(r1, r2); else { double anglea = (r1 * r1 + dd * dd - r2 * r2) / (2.0 * r1 * dd); double angleb = (r2 * r2 + dd * dd - r1 * r1) / (2.0 * r2 * dd); double h1 = r1 * (1 - anglea); double h2 = r2 * (1 - angleb); ans = pi * (r1 - 1.0 / 3.0 * h1) * h1 * h1 + pi * (r2 - 1.0 / 3.0 * h2) * h2 * h2; } printf("%.3f\n", ans); } int main() { int t = 1; scanf("%d", &t); while (t--) run(); return 0; }