列表

详情


NC22564. 球的体积并

描述

某天lililalala正在玩一种奇妙的吃鸡游戏--因为在这个游戏里会同时有两个圆形安全区(他们可能相交)。
lililalala觉得求圆的面积并太简单了,所以想把这个问题升级一下。
现在在三维空间里有 2 个球形安全区,分别用四元组 表示,其中 表示球半径,表示球心
lililalala想知道安全区的总体积是多少?即求这两个球的体积并。


输入描述

输入有两行。
第一行四个实数--第一个球的球心坐标和半径。
第二行四个实数--第二个球的球心坐标和半径。
保证所有输入的坐标和半径的范围都在 内。

输出描述

输出一行一个实数--表示两个球的体积并,你的答案被认为正确,当且仅当绝对误差不超过

示例1

输入:

0 0 0 1
2 0 0 1

输出:

8.3775804

示例2

输入:

0 0 0 1
0 0 0 0.5

输出:

4.1887902

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 4ms, 内存消耗: 512K, 提交时间: 2019-03-13 13:45:50

#include <bits/stdc++.h>
using namespace std;

int main()
{
	double pi=acos(-1.0);
	double x1,y1,z1,r1,x2,y2,z2,r2;
	cin>>x1>>y1>>z1>>r1;
	cin>>x2>>y2>>z2>>r2;
	double d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
	double v1=4.0/3.0*pi*r1*r1*r1;
	double v2=4.0/3.0*pi*r2*r2*r2;
	if(d>=r1+r2)
	{
		printf("%.12lf\n",v1+v2);
	}
	else if(fabs(r1-r2)>=d)
	{
		printf("%.12lf\n",max(v1,v2));
	}
	else
	{
		if(r1<r2)swap(r1,r2);
		double in=pi*(r1+r2-d)*(r1+r2-d)*(d*d+2*d*r2-3*r2*r2+2*d*r1+6*r2*r1-3*r1*r1)/(12.0*d);
		printf("%.12lf\n",v1+v2-in);
	}
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 500K, 提交时间: 2019-03-03 15:36:31

#include<bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
double v(double r){return 4*pi*r*r*r/3;}
int main()
{
	double x1,y1,z1,r1,x2,y2,z2,r2,x,m,n,ans;
	cin>>x1>>y1>>z1>>r1>>x2>>y2>>z2>>r2;
	x=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
	m=max(r1,r2);
	n=min(r1,r2);
	if(x>r1+r2)
		ans=v(r1)+v(r2);
	else if(x+n<=m)
		ans=v(m);
	else
		ans=v(r1)+v(r2)-pi*(n+m-x)*(n+m-x)*(x*x+2*x*m-3*m*m+2*x*n+6*m*n-3*n*n)/12/x;
	printf("%.7lf\n",ans);
	return 0;
}

上一题