传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4741
题意:给你两条异面直线,然你求着两条直线的最短距离,并求出这条中垂线与两直线的交点。
需要注意的是,不知道为什么用double就WA了,但是改为long double就AC了。
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> using namespace std; typedef __int64 LL; const int N=1100; const int INF=0x3f3f3f3f; const long double PI=acos(-1.0); const long double eps=1e-7; bool zero(long double x) { if(fabs(x)<eps) return true; return false; } struct point3D { long double x,y,z; point3D(){}; point3D(long double a,long double b,long double c):x(a),y(b),z(c){} void input() { double a,b,c; scanf("%lf%lf%lf",&a,&b,&c); x=a, y=b, z=c; } 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); } }; struct line { long double a,b,c,d; point3D u,v; }l[33]; long double vlen(point3D a)//向量长度 { return sqrt(a.x*a.x+a.y*a.y+a.z*a.z); } long double dis(point3D a,point3D b)//两点距离 { long double x=a.x-b.x; long double y=a.y-b.y; long double z=a.z-b.z; return sqrt(x*x+y*y+z*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; } long 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); } bool dian_inline(point3D a,point3D b,point3D c)//判断三点共线 { return vlen(xmult(b-a,c-a))<eps; } bool dian_inmian(point3D a,point3D b,point3D c,point3D d)//四点公面 { return zero(dmult(get_faline(a,b,c),d-a)); } long 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); } point3D a,b,c,d; long double F1(point3D a,point3D b) { return ((b.x-a.x)*(b.x-a.x)+(b.y-a.y)*(b.y-a.y)+(b.z-a.z)*(b.z-a.z)); } long double F2() { return ((b.x-a.x)*(d.x-c.x)+(b.y-a.y)*(d.y-c.y)+(b.z-a.z)*(d.z-c.z)); } long double F3ab(point3D a,point3D b) { return ((b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y)+(b.z-a.z)*(c.z-a.z)); } long double F3cd(point3D c,point3D d) { return ((d.x-c.x)*(c.x-a.x)+(d.y-c.y)*(c.y-a.y)+(d.z-c.z)*(c.z-a.z)); } int main() { int T; cin>>T; while(T--) { a.input(); b.input(); c.input(); d.input(); line l1,l2; l1.u=a; l1.v=b; l2.u=c; l2.v=d; printf("%.6lf\n",(double)xian_xian(l1,l2)); long double x[6]; long double xh1,xh2; xh1=F3ab(a,b)*F1(c,d)-F3cd(c,d)*F2(); xh2=F1(a,b)*F1(c,d)-F2()*F2(); x[0]=(b.x-a.x)*xh1/xh2+a.x; x[1]=(b.y-a.y)*xh1/xh2+a.y; x[2]=(b.z-a.z)*xh1/xh2+a.z; long double xx1,xx2,xxx; xx1=F3cd(c,d)*F1(a,b)-F3ab(a,b)*F2(); xx2=F2()*F2()-F1(a,b)*F1(c,d); xxx=xx1/xx2; x[3]=(d.x-c.x)*xxx+c.x; x[4]=(d.y-c.y)*xxx+c.y; x[5]=(d.z-c.z)*xxx+c.z; for(int i=0;i<5;i++) printf("%.6lf ",(double)x[i]); printf("%.6lf\n",(double)x[5]); } return 0; }