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;
}