連結: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 <bits/stdc++.h>
using namespace std;
const double pi = acos(-1);
struct ball{
double x,y,z,r;
ball(double x=0,double y=0,double z=0,double r=0):x(x),y(y),z(z),r(r){}
double dist(ball a){
return sqrt((x-a.x)*(x-a.x)+(y-a.y)*(y-a.y)+(z-a.z)*(z-a.z));
}
double v(){
return pi*r*r*r*4/3;
}
}a,b;
double solve(){
double d = a.dist(b);
if(d-a.r-b.r>0)return a.v()+b.v();
double r1=a.r,r2=b.r;
if(d+r1<r2||d+r2<r1)return max(a.v(),b.v());
double v1=pi/3*(r1-(r1*r1-r2*r2+d*d)/(2*d))*(r1-(r1*r1-r2*r2+d*d)/(2*d));
v1 *= 3*r1- (r1-(r1*r1-r2*r2+d*d)/(2*d));
double v2=pi/3*(r2-(r2*r2-r1*r1+d*d)/(2*d))*(r2-(r2*r2-r1*r1+d*d)/(2*d));
v2 *= 3*r2- (r2-(r2*r2-r1*r1+d*d)/(2*d));
return a.v()+b.v()-(v1+v2);
}
int main(){
scanf("%lf%lf%lf%lf",&a.x,&a.y,&a.z,&a.r);
scanf("%lf%lf%lf%lf",&b.x,&b.y,&b.z,&b.r);
printf("%.7f\n",solve());
return 0;
}
筆者代碼:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const double pi=acos(-1.0);
double x[2],y[2],z[2];
double R,r;
double d;
int main()
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x[0],&y[0],&z[0],&R,&x[1],&y[1],&z[1],&r);
double d=sqrt((x[0]-x[1])*(x[0]-x[1])+(y[0]-y[1])*(y[0]-y[1])+(z[0]-z[1])*(z[0]-z[1]));
double v1=4*pi*R*R*R/3,v2=4*pi*r*r*r/3;
if(d>=R+r)
printf("%.7lf\n",v1+v2);
else if(fabs(R-r)>=d)
printf("%.7lf\n",max(v1,v2));
else
{
if(R<r) swap(R,r);
double insrt=(pi*(R+r-d)*(R+r-d)*(d*d+2*d*r-3*r*r+2*d*R+6*r*R-3*R*R))/(12*d);
printf("%.7lf\n",v1+v2-insrt);
}
return 0;
}
另外附證明公式:
證明:
相交部分體積是由2塊構成的,分别屬于兩個球體。其中一塊的體積公式為(以大球為例):