• 郑轻校赛 2127 tmk射气球 (数学)


    Description

    有一天TMK在做一个飞艇环游世界,突然他发现有一个气球匀速沿直线飘过,tmk想起了他飞艇上有一把弓,他打算拿弓去射气球,为了提高射击的准确性,他首先在飞艇上找到一个离气球最近的一个点,然后射击(即使气球在飞船的正上方),现在求某些时刻飞艇上的点和气球的距离最小是多少(这个最小距离我们简称为飞艇到气球的距离)。

    Input

    第一行一个整数T(T<=20),表示有T组测试数据

    每组测试数据,有两行。

    第一行有5个整数,h,x1,y1,x2,y2,其中h表示飞船的高度,飞船可抽象为一个线段,(x1,y1)(x2,y2)分别是这个线段的端点(有可能会有(x1,y1)(x2,y2)重合的情况)

    第二行有6个整数,x,y,z,X,Y,Z分别表示气球的在第0秒的时候的横坐标,纵坐标,高度,一秒时间气球横坐标的变化量,一秒时间气球纵坐标的变化量,一秒时间气球高度的变化量(如果现在气球在(x0,y0,z0)下一秒坐标就为(x0+X,y0+Y,z0+Z))

    第三行1个整数n,表示询问组数

    接下来的n行,每行一个整数,表示询问的秒数t

    题目涉及的整数除了T以外,范围均为[0,1000]

    Output

    每组询问输出n行,每行输出一个数,表示在t秒的时候飞艇与气球的距离最小是多少,保留两位小数

    Sample Input

    11 1 1 2 20 0 0 4 4 4 203

    Sample Output

    1.7317.92

    分析:

    首先了解一下这道题的思路吧,我没问你要解决的就是求三维空间中的一点到一条直线的距离,我们为你假设空间直线为:Ax+By+Cz+D=0,空间点的坐标为(x1,y1,z1),那么点到直线的距离公式就是abs( Ax1+By1+Cz1+D)/sqrt(AA+BB+CC));

    但是我们也知道这条空间直线是平行于x-0-y平面的,我们可以根据映射吧这条直线和点都映射到x-o-y平面里,求出在二维空间中的点线距离,与点线在三位空间中的z轴上的差距构成直角三角形,其斜边几位所求。

    还需要注意道德一点就是,我们上面所说的都是点到直线的最短距离可以根据距离公式来求出,但是飞船的位置是抽象为一条线段,如果这个点在直线的正上方的话,这个距离无疑是最短的,但是如果没有在正上方,就要取点到线段两个端点距离中的较小值。

    现在我们就要判断这个点到底有没有在这条线段的正上方,应用到三角形求余弦值的公式,如果求得的余弦值为负,该角就是一个钝角,肯定没有在正上方。

    上面都是说线段的斜率存在的情况,也有可能线段的斜率压根不存在,这样的话也是要考虑点在不在线正上方,在的话就是横坐标的差值,不再的话还是点到线段两个端点距离的较小值。

    代码:

        #include<bits/stdc++.h>
        using namespace std;
        int main()
        {
            int n;
            double h1,x1,y1,x2,y2;  ///飞船
            double x3,y3,z3,X,Y,Z;///气球
            int m,t;                 ///询问次数,每次的时间
            scanf("%d",&n);
            while(n--)
            {
                scanf("%lf%lf%lf%lf%lf",&h1,&x1,&y1,&x2,&y2);///飞船的相关信息
                scanf("%lf%lf%lf%lf%lf%lf",&x3,&y3,&z3,&X,&Y,&Z);///气球的相关信息
                double c;
                c=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));///抽象为飞船的两个端点间的距离,即飞船的长度
                scanf("%d",&m);
                while(m--)
                {
                    scanf("%d",&t);
                    int x=x3+X*t;            ///气球t秒的坐标
                    int y=y3+Y*t;
                    int z=z3+Z*t;
                    double b,a;
                    double s;
                    double k,C;
                    b=sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));///气球的当前位置与飞船的左端点之间的距离
                    a=sqrt((x1-x)*(x1-x)+(y1-y)*(y1-y));///起球的当前位置与飞船的右端点之间的距离
                    if(x2==x1)///即飞船这条线段斜率不存在的时候
                    {
                        if(y>=y1&&y<=y2)///如果当前气球的位置在这条直线的上方
                            s=x-x1;///距离就是横坐标的差值
                        else
                            s=min(a,b);
                        //printf("%lf
    ",s);
                    }
                    else
                    {
                        k=(y2-y1)/(x2-x1);///飞船所在的直线的斜率
                        C=y1-k*x1;///飞船所在的直线的截距
                        double d=abs((k*x-y+C)/sqrt(k*k+1));///根据点到直线的距离公式,求得当前气球到直线的垂距
                         if(a*a+c*c<b*b||c*c+b*b<a*a)///应用三角形的余弦公式,得到这样的话相当于气球与飞船构成一个钝角三角形
                            s=min(a,b);
                        else
                            s=d;
                    }
                    printf("%.2lf
    ",sqrt(s*s+(z-h1)*(z-h1)));
                }
            }
        }
    
  • 相关阅读:
    针对专业人员的 TensorFlow 2.0 入门
    学习深度学习过程中的一些问题
    Leetcode_06_ZigZag Conversion (easy)
    leetcode_07_Reverse Integer (easy)
    独立游戏人:像素风格游戏制作分享(转)
    关于iphone开发中的@property和@synthesize的一些见解(转)
    iphone开发cocoa中nil,NSNull,Nil的使用区别
    Xcode6.1创建仅xib文件无storyboard的hello world应用(转)
    iOS 学习资料整理(转)
    hdoj1042ac
  • 原文地址:https://www.cnblogs.com/cmmdc/p/6729581.html
Copyright © 2020-2023  润新知