题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4741
题目大意 给你4个点 确定两条异面直线,求他们之间的距离和公垂线段的垂足。
这里从twj1993那学的用直线参数方程+偏导数的方法,甚至可以解决n维坐标下的问题。
设第一条直线的参数方程是x=x1+(x3-x1)*t1 , y=...,z=..... 第二条直线的参数方程同理可设(t2为参数)。
然后两点之间的距离就可以表示为t1,t2的二元函数,令偏导为0就可以了。
为了方便起见,变量用x,y代替。
然后求函数系数的时候发现x,y是对称的,只需要把x改成y,z加上去就可以了
最后,很关键的一点,double 会wa的,只有输入输出的时候可以用double ,其余要用long double
代码:
#include<iostream> #include<cstdio> #include<cmath> using namespace std; long double det2(long double a11,long double a12,long double a21,long double a22) { return a11*a22-a12*a21; } int main() { double p[12]; long double x1,y1,z1,x2,y2,z2,x3,y3,z3,x4,y4,z4; long double A,B,C,D,E; long double DD; long double Dx,Dy,x,y; double p1x,p1y,p1z,p2x,p2y,p2z; long double distance; int T; cin>>T; while(T--) { for(int i=0;i<12;i++) scanf("%lf",&p[i]); x1=p[0]; y1=p[1]; z1=p[2]; x2=p[3]; y2=p[4]; z2=p[5]; x3=p[6]; y3=p[7]; z3=p[8]; x4=p[9]; y4=p[10]; z4=p[11]; A=(x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)+(z2-z1)*(z2-z1); B=(x4-x3)*(x4-x3)+(y4-y3)*(y4-y3)+(z4-z3)*(z4-z3); C=-2*(x2-x1)*(x4-x3)-2*(y2-y1)*(y4-y3)-2*(z2-z1)*(z4-z3); D=2*(y2-y1)*(y1-y3)+2*(x2-x1)*(x1-x3)+2*(z2-z1)*(z1-z3); E=-2*(x4-x3)*(x1-x3)-2*(y1-y3)*(y4-y3)-2*(z1-z3)*(z4-z3); DD=det2(2*A,C,C,2*B); Dx=det2(-D,C,-E,2*B); Dy=det2(2*A,-D,C,-E); x=Dx/DD; y=Dy/DD; p1x=x1+(x2-x1)*x; p1y=y1+(y2-y1)*x; p1z=z1+(z2-z1)*x; p2x=x3+(x4-x3)*y; p2y=y3+(y4-y3)*y; p2z=z3+(z4-z3)*y; // cout<<p1x<<" "<<p2y<<" "<<p2x<<" "<<p2y<<endl; long double distance=(p1x-p2x)*(p1x-p2x)+(p1y-p2y)*(p1y-p2y)+(p1z-p2z)*(p1z-p2z); distance=sqrt(distance); double ans=distance; printf("%.6lf ",ans); printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf ",p1x,p1y,p1z,p2x,p2y,p2z); } }