ACM 2018 南京区域赛 D - Country Meow (最小圆覆盖/三分)

Gym 101981D

题目大意:

       宇宙中有n个城市,需要建一个指挥部,使得指挥部与所有城市之间的距离尽可能小。问指挥部和最远城市之间的最小欧几里得距离是多少。

题解:

     就是让球这n个点的最小球覆盖,指挥部是圆心,球的半径就是指挥部到最远城市之间的欧几里得距离

     红书上有板子,直接套就可以过了

     这么长的两页板子经常会漏掉一些,所以一定敲完之后查下错,不然敲完之后WA可还可能觉得是套板子不对......

     注意定义Tpoint的xyz类型应该用double,而不是int!!!

#include
#include
#define ll long long
#define INF 1000000007
#define eps 1e-6
#define mod 1000000007
#define double long double
using namespace std;
struct Tpoint
{
    double x,y,z;
};
int npoint,nouter;
Tpoint pt[200000],outer[4],res;
double radius,tmp;
inline double dist(Tpoint p1,Tpoint p2)
{
    double dx=p1.x-p2.x,dy=p1.y-p2.y,dz=p1.z-p2.z;
    return (dx*dx+dy*dy+dz*dz);
}
inline double dot(Tpoint p1,Tpoint p2)
{
    return p1.x*p2.x+p1.y*p2.y+p1.z*p2.z;
}
void ball()
{
    Tpoint q[3];
    double m[3][3],sol[3],L[3],det;
    int i,j;
    res.x=res.y=res.z=radius=0;
    switch(nouter)
    {
    case 1:
        res=outer[0];
        break;
    case 2:
        res.x=(outer[0].x+outer[1].x)/2;
        res.y=(outer[0].y+outer[1].y)/2;
        res.z=(outer[0].z+outer[1].z)/2;
        radius=dist(res,outer[0]);
        break;
    case 3:
        for(int i=0; i<2; ++i)
        {
            q[i].x=outer[i+1].x-outer[0].x;
            q[i].y=outer[i+1].y-outer[0].y;
            q[i].z=outer[i+1].z-outer[0].z;
        }
        for(int i=0; i<2; ++i)
            for(int j=0; j<2; ++j)
                m[i][j]=dot(q[i],q[j])*2;
        for(int i=0; i<2; ++i)
            sol[i]=dot(q[i],q[i]);
        if(fabs(det=m[0][0]*m[1][1]-m[0][1]*m[1][0])eps)
            {
                outer[nouter]=pt[i];
                ++nouter;
                minball(i);
                --nouter;
                if(i>0)
                {
                    Tpoint Tt=pt[i];
                    memmove(&pt[1],&pt[0],sizeof(Tpoint)*i);
                    pt[0]=Tt;
                }
            }
    }
}
double smallest_ball()
{
    radius=-1;
    for(int i=0; ieps)
        {
            nouter=1;
            outer[0]=pt[i];
            minball(i);
        }
    }
    return sqrt(radius);
}
int main()
{
    //freopen("input.txt","r",stdin);
    while(cin>>npoint)
    {
        for(int i=0; i>pt[i].x>>pt[i].y>>pt[i].z;
        }
        cout<

 

你可能感兴趣的:(ACM,三分,计算几何,ACM,三分,计算几何)