题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4617
题意:说白了就是求空间上两跳直线的距离 - 两个半径的最小值。
AC代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <list>
#include <deque>
#include <queue>
#include <iterator>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <cctype>
#include <ctime>
#pragma comment(linker, "/STACK:16777216")
using namespace std;
typedef __int64 LL;
const int N=50005;
const int M=55555555;
const int INF=0x3f3f3f3f;
const double PI=acos(-1.0);
const double eps=1e-7;
bool zero(double x)
{
if(fabs(x)<eps)
return true;
return false;
}
struct point3D
{
double x,y,z;
point3D(){};
point3D(double a,double b,double c):x(a),y(b),z(c){}
void input()
{
scanf("%lf%lf%lf",&x,&y,&z);
}
friend point3D operator -(const point3D &a,const point3D &b)
{
return point3D(a.x-b.x,a.y-b.y,a.z-b.z);
}
friend point3D operator +(const point3D &a,const point3D &b)
{
return point3D(a.x+b.x,a.y+b.y,a.z+b.z);
}
}p[33][4];
double r[33];
struct line
{
double a,b,c,d;
point3D u,v;
}l[33];
double vlen(point3D a)
{
return sqrt(a.x*a.x+a.y*a.y+a.z*a.z);
}
point3D xmult(point3D u,point3D v)
{
point3D ret;
ret.x=u.y*v.z-v.y*u.z;
ret.y=u.z*v.x-u.x*v.z;
ret.z=u.x*v.y-u.y*v.x;
return ret;
}
double dmult(point3D u,point3D v)
{
return u.x*v.x+u.y*v.y+u.z*v.z;
}
point3D get_faline(point3D a,point3D b,point3D c)
{
return xmult(b-a,c-a);
}
double xian_xian(line l1,line l2)
{
point3D n=xmult(l1.u-l1.v,l2.u-l2.v);
return fabs(dmult(l1.u-l2.u,n))/vlen(n);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=3;j++)
p[i][j].input();
r[i]=vlen(p[i][1]-p[i][2]);
}
for(int i=1;i<=n;i++)
{
l[i].u=p[i][1];
l[i].v=p[i][1]+get_faline(p[i][1],p[i][2],p[i][3]);
}
double Min=INF;
int flag=0;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
double tmp=xian_xian(l[i],l[j]);
tmp-=(r[i]+r[j]);
if(tmp<=0)
{
flag=1;
i=j=300;
break;
}
if(tmp<Min)
Min=tmp;
}
}
if(flag)
printf("Lucky\n");
else
printf("%.2f\n",Min);
}
return 0;
}