【题意】N<=30无限长圆柱体,求任意两个圆柱体之间的最短距离。

【解题方法】圆柱之间的距离就是中轴线的距离,平行的话很简单,异面的话不会算,记录一下模板吧。

【AC code】


<nobr>#include <bits/stdc++.h>
using namespace std;
const double eps=1e-8;
int sgn(double x)
{
    return x<-eps?-1:x>eps;
}
struct node{
    double x,y,z;
    void read()
    {
        scanf("%lf%lf%lf",&x,&y,&z);
    }
    node operator+(const node &p){
        return {x+p.x,y+p.y,z+p.z};
    }
    node operator-(const node &p){
        return {x-p.x,y-p.y,z-p.z};
    }
    double operator*(const node &p){
        return x*p.x+y*p.y+z*p.z;
    }
    node operator^(const node &p){
        return {y*p.z-z*p.y,z*p.x-x*p.z,x*p.y-y*p.x};
    }
    double length()
    {
        return sqrt(*this **this);
    }
}p[33][3];
using point=node;
double r[33];//圆柱的半径
point normal[33];//计算法向量
bool pingxing(point a,point b)
{
    return sgn((a^b).length())<=0;
}
double pointtoline(point a,point b,point c)
{
    point fa=a-b;
    return (fa^c).length()/c.length();
}
double linetoline(point a,point b,point c,point d)
{
    point fa=b^d;
    return abs((a-c)*fa)/fa.length();
}
int main()
{
    int t,n;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1; i<=n; i++){
            for(int j=0; j<3; j++){
                p[i][j].read();
            }
            r[i]=(p[i][1]-p[i][0]).length();
            normal[i]=(p[i][1]-p[i][0])^(p[i][2]-p[i][0]);
        }
        double ans=1e18;
        for(int i=1; i<=n; i++){
            for(int j=i+1; j<=n; j++){
                double d=0;
                if(pingxing(normal[i],normal[j])) d=pointtoline(p[i][0],p[j][0],normal[j]);
                else d=linetoline(p[i][0],normal[i],p[j][0],normal[j]);
                ans=min(ans,max(0.00,d-r[i]-r[j]));
            }
        }
        if(sgn(ans)==0){
            puts("Lucky");
        }else{
            printf("%.2f\n",ans);
        }
    }
}