CCPC-Wannafly Winter Camp Day2 Div.2 H Cosmic Cleaner - 两球相交体积

Cosmic Cleaner

题目描述

在一片小行星带里有 n 颗小行星,它们在万有引力的作用下绕着一颗行星旋转。在这一刻时,它们之间不存在碰撞的情况。一位清洁工奉命前来清理这颗行星,Ta 会动用某种先进技术使这颗行星顷刻间从宇宙中消失,任何距离这颗行星的中心在一定范围内的事物都会在一瞬间被清除。假设这些天体都是完整的球体,你能计算出清除的区域里有多少体积的事物原本属于这些小行星吗?

注意,这些天体在此刻满足两两不存在交集的条件。

下图是对样例的解释,其中清理区域是标记为红色的球体内部,而小行星则被依次标记为橙色、蓝色和绿色。

spheres.png

输入描述

输入包含多组测试数据。第一行包含一个整数 T,表示测试数据的组数。随后的内容是各组测试数据。对于每组测试数据:

第一行包含一个整数 n。

接下来的 n 行里,每行包含四个整数 x, y, z 和 r,表示有一颗中心位于 (x, y, z)半径为 r 的小行星。

最后一行包含四个整数 x‘, y', z′ 和 r′,表示行星的中心位于 (x′,y′,z′),而清洁工的清理半径为 r′(一个大于该行星半径的值)。

  • 1≤T≤6000
  • 1≤n≤100
  • −10^3≤x,y,z,x′,y′,z′≤10^3
  • 10^31≤r,r′≤10^3

输出描述

对于每组测试数据,输出一行Case #x: y,其中x是测试数据的编号(从 11 开始编号),y是这组数据的答案,要求相对误差或绝对误差不超过 10^{-6}10−6。

严格来讲,如果你的答案是 aa,而标准答案是 bb,那么当 \frac{|a - b|}{\max{1, |b|}} \leq 10^{-6}max1,∣b∣∣a−b∣​≤10−6 时你的答案会被认为是正确的。

样例输入 1 

1
3
5 5 5 2
-6 -7 6 1
6 -5 0 3
1 -1 0 10

样例输出 1

Case #1: 142.76246874761383764962

解题思路:

很明显的就是求两个球的相交体积。

(学习公式点我)

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+5;
const double PI = acos(-1);
int t;
int n;
double X, Y, Z, R;
struct ball{
	double x, y, z, r;
}b[105];

double dis(ball a){
	return sqrt((a.x-X)*(a.x-X) + (a.y-Y)*(a.y-Y) + (a.z-Z)*(a.z-Z));
}

int main(){
	scanf("%d", &t);
	for(int k = 1; k <= t; ++k){
		scanf("%d", &n);
		double ans = 0;
		for(int i = 0; i < n; ++i){
			scanf("%lf %lf %lf %lf", &b[i].x, &b[i].y, &b[i].z, &b[i].r);
		}
		scanf("%lf %lf %lf %lf", &X, &Y, &Z, &R);
		for(int i = 0; i < n; ++i){
			double d = dis(b[i]);
			if(b[i].r+R <= d){
				continue;
			}
			else if(b[i].r+d <= R){
				ans += 4 * PI * b[i].r * b[i].r * b[i].r / 3;
			}
			else {
				double h1 = R - (((R * R + d * d - b[i].r * b[i].r) / (2 * R * d))) * R;
				double h2 = b[i].r - ((b[i].r * b[i].r + d * d - R * R) / (2 * b[i].r * d)) * b[i].r;
				double Big = PI * (3 * R - h1) * h1 * h1 / 3;
				double Small = PI * (3 * b[i].r - h2) * h2 * h2 / 3;
				ans += Big + Small;
			}
		}
		printf("Case #%d: %.10lf\n", k, ans);
	}
	return 0;
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值