题解 | #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;
}
全部评论

相关推荐

03-02 02:44
门头沟学院 Java
咩咩子_:92直接梭哈
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务