F题题解
原题链接 题目思路:其实这道题就是考了个阿波罗尼斯圆,如果知道这个知识点的话就可以直接求出半径和球心坐标,再判断一下两球是相交,相离还是一个球在另一个球里面,之后就是敲代码的功夫了
#include<bits/stdc++.h>
using namespace std;
double d(double x1,double y1,double z1,double x2,double y2,double z2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));};
double solve(double x1,double y1,double z1,double x2,double y2,double z2,int k){
double dis=d(x1,y1,z1,x2,y2,z2);
return abs(dis*k*1.0/(k*k-1));
}
double cals(double x1,double y1,double z1,double x2,double y2,double z2,double r1,double r2){
double dis=d(x1,y1,z1,x2,y2,z2);
double alpha=(dis*dis+r1*r1-r2*r2)/(2*r1*dis);
double h1=r1-r1*alpha;
double beta=(dis*dis+r2*r2-r1*r1)/(2*r2*dis);
double h2=r2-r2*beta;
double s1=M_PI*h1*h1*(3*r1-h1)/3.0;
double s2=M_PI*h2*h2*(3*r2-h2)/3.0;
return s1+s2;
}
double calo(double dis,double r,int k,double a,double b){
return ((r*1.0/dis)+k*1.0/(k+1))*(a-b)+b;
}
int main(){
int t;
cin>>t;
while(t--){
double x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4;
int k1,k2;
cin>>x1>>y1>>z1>>x2>>y2>>z2>>x3>>y3>>z3>>x4>>y4>>z4;
cin>>k1>>k2;
double r1=solve(x1,y1,z1,x2,y2,z2,k1);
double r2=solve(x3,y3,z3,x4,y4,z4,k2);
double ox1=calo(d(x1,y1,z1,x2,y2,z2),r1,k1,x2,x1);
double oy1=calo(d(x1,y1,z1,x2,y2,z2),r1,k1,y2,y1);
double oz1=calo(d(x1,y1,z1,x2,y2,z2),r1,k1,z2,z1);
double ox2=calo(d(x3,y3,z3,x4,y4,z4),r2,k2,x4,x3);
double oy2=calo(d(x3,y3,z3,x4,y4,z4),r2,k2,y4,y3);
double oz2=calo(d(x3,y3,z3,x4,y4,z4),r2,k2,z4,z3);
double dis=d(ox1,oy1,oz1,ox2,oy2,oz2);
//cout<<dis<<' '<<r1<<' '<<r2<<endl;
if(dis>=r1+r2)cout<<0<<endl;
else if(dis+r1<=r2){
cout<<4*M_PI*r1*r1*r1/3.0<<endl;
}
else if(dis+r2<=r1){
cout<<4*M_PI*r2*r2*r2/3.0<<endl;
}
else printf("%.3f\n",cals(ox1,oy1,oz1,ox2,oy2,oz2,r1,r2));
}
return 0;
}