链接:https://ac.nowcoder.com/acm/contest/373/E
来源:牛客网
题目描述
某天lililalala正在玩一种奇妙的吃鸡游戏--因为在这个游戏里会同时有两个圆形安全区(他们可能相交)。
lililalala觉得求圆的面积并太简单了,所以想把这个问题升级一下。
现在在三维空间里有 2 个球形安全区,分别用四元组 <x1,y1,z1,r1> <x1,y1,z1,r1> 和 <x2,y2,z2,r2> <x2,y2,z2,r2>表示,其中 r1、r2 r1、r2表示球半径, (x1,y1,z1) (x1,y1,z1)和 (x2,y2,z2) (x2,y2,z2)表示球心
lililalala想知道安全区的总体积是多少?即求这两个球的体积并。
输入描述:
输入有两行。
第一行四个实数 x1,y1,z1,r1 x1,y1,z1,r1--第一个球的球心坐标和半径。
第二行四个实数 x2,y2,z2,r2 x2,y2,z2,r2--第二个球的球心坐标和半径。
保证所有输入的坐标和半径的范围都在 [−100,100] [−100,100] 内。
输出描述:
输出一行一个实数--表示两个球的体积并,你的答案被认为正确,当且仅当绝对误差不超过 10−6 10−6。
示例1
输入
复制
0 0 0 1 2 0 0 1
输出
复制
8.3775804
示例2
输入
复制
0 0 0 1 0 0 0 0.5
输出
复制
4.1887902
代码:
#include<iostream>
#include<algorithm>
#include<math.h>
#include<stdio.h>
using namespace std;
const double pi=acos(-1.0);
int main()
{
double x1,x2,y1,y2,z1,z2,r1,r2;
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&z1,&r1,&x2,&y2,&z2,&r2);
double d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
double ans=4.0*pi*(r1*r1*r1+r2*r2*r2)/3.0;
if(d>=r1+r2)
printf("%.7lf",ans);
else if(d<=fabs(r1-r2))
{
double r=max(r1,r2);
printf("%.7lf",4.0*pi*(r*r*r)/3.0);
}
else
{
double h1=r1-(r1*r1-r2*r2+d*d)/(2.0*d);
double h2=r2-(r2*r2-r1*r1+d*d)/(2.0*d);
double v1=pi*h1*h1*(3.0*r1-h1)/3.0;
double v2=pi*h2*h2*(3.0*r2-h2)/3.0;
printf("%.7lf\n",ans-v1-v2);
}
return 0;
}