【题意】给一个四面体,要求出这个四面体的内接球的半径和内接球的球心。

【解题方法】网上抄一个公式,然后计算几何模板套一套就可以了。。。。赛后顺便来复习一下计算几何的基础知识。

【AC 代码】

#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;

struct point
{
    double x,y,z;
} s[4];
//点积
double dot(point a,point b)
{
    return a.x*b.x+a.y*b.y+a.z*b.z;
}
//差集
point xmult(point u,point v)
{
    point c;
    c.x=u.y*v.z-u.z*v.y;
    c.y=v.x*u.z-u.x*v.z;
    c.z=u.x*v.y-v.x*u.y;
    return c;
}
//矢量差
point smult(point u,point v)
{
    point c;
    c.x=u.x-v.x;
    c.y=u.y-v.y;
    c.z=u.z-v.z;
    return c;
}
//矢量和
point amult(point u,point v)
{
    point c;
    c.x=u.x+v.x;
    c.y=u.y+v.y;
    c.z=u.z+v.z;
    return c;
}
//取平面法向量
point prec(point a,point b,point c)
{
    return xmult(smult(a,b),smult(b,c));
}
//两点之间的距离
double dis(point a,point b)
{
    double dx=(a.x-b.x);
    double dy=(a.y-b.y);
    double dz=(a.z-b.z);
    return fabs(sqrt(dx*dx+dy*dy+dz*dz));
}
//计算三角形的面积
double getsquare(point a,point b,point c)
{
    double l1=dis(a,b);
    double l2=dis(a,c);
    double l3=dis(b,c);
    double p=(l1+l2+l3)/2;
    return sqrt(p*(p-l1)*(p-l2)*(p-l3));
}
//判断四点共面
bool check(point a,point b,point c,point d)
{
    if(dot(prec(a,b,c),smult(d,a))==0.00000) return true;
    else return false;
}
int main()
{
    while(~scanf("%lf%lf%lf",&s[0].x,&s[0].y,&s[0].z))
    {
        for(int i=1; i<4; i++) scanf("%lf%lf%lf",&s[i].x,&s[i].y,&s[i].z);
        if(check(s[0],s[1],s[2],s[3]))
        {
            puts("O O O O");
        }
        else
        {
            double V;
            //底面积
            double S=getsquare(s[0],s[1],s[2]);
            //求单位法向量
            point  fa=prec(s[0],s[1],s[2]);
            double xx=sqrt(fa.x*fa.x+fa.y*fa.y+fa.z*fa.z);
            fa.x=fa.x/xx,fa.y=fa.y/xx,fa.z=fa.z/xx;
            //求高
            point h=smult(s[0],s[3]);
            double H=dot(h,fa);
            V=S*H*1/3;
            V=fabs(V);
            double s3=getsquare(s[0],s[1],s[2]);
            double s0=getsquare(s[3],s[1],s[2]);
            double s1=getsquare(s[0],s[3],s[2]);
            double s2=getsquare(s[0],s[1],s[3]);
            double ss=s0+s1+s2+s3;
//        printf("s0: %.4f s1: %.4f s2:%.4f s3: %.4f\n",s0,s1,s2,s3);
//        printf("V:  %.4f\n",V);
//        printf("ss: %.4f\n",ss);
            double xi=s0*s[0].x+s1*s[1].x+s2*s[2].x+s3*s[3].x;
            double yi=s0*s[0].y+s1*s[1].y+s2*s[2].y+s3*s[3].y;
            double zi=s0*s[0].z+s1*s[1].z+s2*s[2].z+s3*s[3].z;
            printf("%.4f %.4f %.4f %.4f\n",xi/ss,yi/ss,zi/ss,3*V/ss);
        }
    }
}