题目地址: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; }