zoukankan      html  css  js  c++  java
  • hdu 4617 Weapon【异面直线距离——基础三维几何】

    链接:


    Weapon

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 224    Accepted Submission(s): 178


    Problem Description
      Doctor D. are researching for a horrific weapon. The muzzle of the weapon is a circle. When it fires, rays form a cylinder that runs through the circle verticality in both side. If one cylinder of rays touch another, there will be an horrific explosion. Originally, all circles can rotate easily. But for some unknown reasons they can not rotate any more. If these weapon can also make an explosion, then Doctor D. is lucky that he can also test the power of the weapon. If not, he would try to make an explosion by other means. One way is to find a medium to connect two cylinder. But he need to know the minimum length of medium he will prepare. When the medium connect the surface of the two cylinder, it may make an explosion.
     

    Input
      The first line contains an integer T, indicating the number of testcases. For each testcase, the first line contains one integer N(1 < N < 30), the number of weapons. Each of the next 3N lines&#160; contains three float numbers. Every 3 lines represent one weapon. The first line represents the coordinates of center of the circle, and the second line and the third line represent two points in the circle which surrounds the center. It is supposed that these three points are not in one straight line. All float numbers are between -1000000 to 1000000.
     

    Output
      For each testcase, if there are two cylinder can touch each other, then output 'Lucky', otherwise output then minimum distance of any two cylinders, rounded to two decimals, where distance of two cylinders is the minimum distance of any two point in the surface of two cylinders.
     

    Sample Input
    3 3 0 0 0 1 0 0 0 0 1 5 2 2 5 3 2 5 2 3 10 22 -2 11 22 -1 11 22 -3 3 0 0 0 1 0 1.5 1 0 -1.5 112 115 109 114 112 110 109 114 111 -110 -121 -130 -115 -129 -140 -104 -114 -119.801961 3 0 0 0 1 0 1.5 1 0 -1.5 112 115 109 114 112 110 109 114 111 -110 -121 -130 -120 -137 -150 -98 -107 -109.603922
     

    Sample Output
    Lucky 2.32 Lucky
     

    Source
     

    Recommend
    zhuyuanchen520
     


    其实是盗版的KB大神的了。。。虽然他已经告诉了我是求异面直线的距离ORz kuangbin



    题意:


     博士发明了一种武器,武器的枪口是圆的,一旦点火,那么能量射线就会从圆的两端都出来
     【这样就形成了底面圆确定,长度不限的圆柱体】
    一旦有两个这样的能量圆柱体相遇【个人认为是包含了相切或者一个圆柱体包含了一个圆柱体的情况也算的,不过数据中没有】
    那么就会发生爆炸,这样博士就能检测武器的威力了。

                                                        
    我认为只要不是第一种情况都应该可以输出  Lucky


    下面给出 T 组测试数据
    每组测试数据包含了 N  个圆柱体
    对于每一个圆柱体给出了它的底面圆的圆心坐标和底面圆圆周上的两个点

    如果给出的圆所形成的圆柱体至少能有两个相遇,那么显然博士可以直接检测他们的威力,直接输出 Lucky

    如果没有任何的圆柱体相遇,那么就求出所有的圆柱体中相邻最近的距离,也就是找最小的距离了。


    算法:


    异面直线距离 : 【百度百科

    向量方法:先求两异面直线的公共法向量,再求两异面直线上两点的连结线段在公共法向量上的射影长。

    思路:

    把每一个圆面都与其它所有的圆面两两比较,看他们所形成的圆柱体是否有相交的

    如何实现:求出圆柱体间的轴线间的距离与他们的半径比较就好了。

    个人认为不用考虑轴线是否平行甚至共线的问题,应该是数据比较水了,怎么乱搞都过了Orz


    code: 

    Accepted 4617 15MS 244K 3486 B C++ free斩
    #include<stdio.h>
    #include<math.h>
    #include<algorithm>
    using namespace std;
    
    const int maxn = 30+10;
    
    const double eps = 1e-10;
    int dcmp(double x) //精度
    {
        if(fabs(x) < eps) return 0;
        else return x < 0 ? -1 : 1;
    }
    
    struct Point3D{
        double x;
        double y;
        double z;
    
        Point3D() {}
        Point3D(double _x, double _y, double _z){
            x = _x;
            y = _y;
            z = _z;
        }
    
        Point3D operator -(const Point3D &b) const
        {
            return Point3D(x-b.x, y-b.y, z-b.z);
        }
        double operator *(const Point3D &b) const //点积
        {
            return x*b.x+y*b.y+z*b.z;
        }
        Point3D operator ^(const Point3D &b) const //叉积
        {
            return Point3D(y*b.z-z*b.y, z*b.x-x*b.z, x*b.y-y*b.x);
        }
    
        void input()
        {
            scanf("%lf%lf%lf", &x,&y,&z);
        }
    };
    typedef Point3D Vector3D;
    
    struct Circle{
        Point3D o, p1, p2;
    
        void input()
        {
            o.input();
            p1.input();
            p2.input();
        }
    }circle[maxn];
    
    double Length3D(Point3D p) //向量长度
    {
        return sqrt(p*p);
    }
    
    //两异面直线距离【两直线上的点的连线在其法向量上的投影】
    double cal(Point3D p1, Vector3D k1, Point3D p2, Vector3D k2)
    {
        Point3D nV = k1^k2; //normalVector
        return fabs(nV*(p1-p2)) / Length3D(nV);
    }
    
    int main()
    {
        int T;
        int n;
        scanf("%d", &T);
        while(T--)
        {
            scanf("%d", &n);
            for(int i = 0; i < n; i++)
                circle[i].input();
            bool flag = false;
            double Min = 3000000;
    
            for(int i = 0; i < n && !flag; i++)
            {
                for(int j = i+1; j < n && !flag; j++)
                {
                    Circle c1 = circle[i];
                    Circle c2 = circle[j];
    
                    double r1 = Length3D(c1.p1-c1.o); //圆半径
                    double r2 = Length3D(c2.p1-c2.o);
                    Vector3D k1 = (c1.p1-c1.o)^(c1.p2-c1.o); //轴线的方向
                    Vector3D k2 = (c2.p1-c2.o)^(c2.p2-c2.o);
    
                    double d = cal(c1.o, k1, c2.o, k2); //两异面直线距离
                    if(d <= r1+r2) //两圆相交或相切甚至内含应该都可以【题目不严谨没有相切和内含的数据】
                    {
                        flag = true;
                        break;
                    }
                    Min = min(Min, d-r1-r2);
                }
            }
            if(flag) printf("Lucky
    ");
            else if(dcmp(Min) <= 0) printf("Lucky
    ");
            else printf("%.2lf
    ", Min);
        }
        return 0;
    }
    


  • 相关阅读:
    PipeCAD Grid
    Java -- MyBatis学习笔记11、PageHelper
    Java -- MyBatis学习笔记10、主配置文件
    Java -- MyBatis学习笔记9、动态SQL
    Java -- MyBatis学习笔记8、模糊查询like
    Java -- MyBatis学习笔记7、# 和 $的区别
    Java -- MyBatis学习笔记6、参数传递
    Java -- MyBatis学习笔记5、getMapper
    Java -- MyBatis学习笔记4、简单CURD
    Java -- MyBatis学习笔记3、输出日志
  • 原文地址:https://www.cnblogs.com/freezhan/p/3238972.html
Copyright © 2011-2022 走看看