• HDU 4741 Save Labman No.004 2013 ACM/ICPC 杭州网络赛


    传送门: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
    ",(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
    ",(double)x[5]);
        }
        return 0;
    }
    


     

  • 相关阅读:
    下四国的排长和下四国的小兵 (转载)
    RSS Bandit 不能显示中文界面的解决方法
    Google桌面搜索(GDS)插件的开发工具
    编写VxWorks的Hello World程序
    Visual Studio 2005 Express October 2004 CTP完整版本的下载
    压缩.NET可执行文件的工具
    支持x64的开发工具
    Visual Studio.NET 2002的Service Pack 1发布了
    Windows 嵌入式开发的一些Blog
    利用BITSADMIN获得下载地址
  • 原文地址:https://www.cnblogs.com/riskyer/p/3324940.html
Copyright © 2020-2023  润新知