【zzulioj 2127】 tmk射气球

2018-06-17 22:47:41来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

比较简单的题,直接求空间中一个点到直线的距离而已,这道题说了直线和水平的平面 平行,我们可以先求投影到直线的距离,然后再算当前点到直线的距离。

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

1 1 1 1 2 2 0 0 0 4 4 4 2 0 3

Sample Output

1.73 17.92
 
  1 #include <iostream>
  2 #include<string>
  3 #include<cstring>
  4 #include<vector>
  5 #include<set>
  6 #include<map>
  7 #include<stack>
  8 #include<queue>
  9 #include<list>
 10 #include<cmath>
 11 #include<algorithm>
 12 #include<cstdio>
 13 #include <bitset>
 14 #include <climits>
 15 #include <time.h>
 16 #include<iomanip>
 17 #define INF 0x3f3f3f3f
 18 using namespace std;
 19 #define ll long long
 20 #define eps 1e-8
 21 #define zero(x) (((x>0)?(x):-(x))<eps)
 22 struct point{double x,y;};
 23 
 24 double distancen(point p1,point p2)
 25 {
 26     return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
 27 }
 28 ll xmult(point p1,point p2,point p0)
 29 {
 30     return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
 31 
 32 }
 33 point intersection(point u1,point u2,point v1,point v2)
 34 {
 35     point ret = u1;
 36     double t = ((u1.x-v1.x)*(v1.y-v2.y)-(u1.y-v1.y)*(v1.x-v2.x))
 37                 /((u1.x-u2.x)*(v1.y-v2.y)-(u1.y-u2.y)*(v1.x-v2.x));
 38     ret.x+=(u2.x-u1.x)*t;
 39     ret.y+=(u2.y-u1.y)*t;
 40     return ret;
 41 
 42 }
 43 
 44 point ptoseg(point p,point l1,point l2)
 45 {
 46     point t = p;
 47     t.x+=l1.y-l2.y;
 48     t.y+=l2.x-l1.x;
 49 
 50     if(xmult(l1,t,p)*xmult(l2,t,p)>eps)
 51     {
 52         return (distancen(p,l1)<distancen(p,l2))?l1:l2;
 53     }
 54     return intersection(p,t,l1,l2);
 55 }
 56 
 57 int dot_online(point p,point l1,point l2)
 58 {
 59     return (zero(xmult(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)==0&&(l1.y-p.y)*(l2.y-p.y)==0);
 60 }
 61 
 62 int main()
 63 {
 64     //freopen("D://in.txt","r",stdin);
 65     //freopen("D://out.txt","w",stdout);
 66     int T;
 67     scanf("%d",&T);
 68     while(T--)
 69     {
 70         bool mark = false;
 71         point ll1,ll2;
 72         double h,x1,y1,x2,y2;
 73         scanf("%lf%lf%lf%lf%lf",&h,&x1,&y1,&x2,&y2);
 74         ll1.x = x1;ll1.y = y1;
 75         ll2.x = x2;ll2.y = y2;
 76         if(x1==x2&&y1==y2)
 77             mark = true;
 78 
 79         double x,y,z,X,Y,Z;
 80         scanf("%lf%lf%lf%lf%lf%lf",&x,&y,&z,&X,&Y,&Z);
 81         int n;
 82         scanf("%d",&n);
 83         while(n--)
 84         {
 85             int t;
 86             scanf("%d",&t);
 87             point newp;
 88             newp.x = x+t*X;
 89             newp.y = y+t*Y;
 90             double zz = z+t*Z;
 91             if(mark)
 92             {
 93                 double res = distancen(newp,ll1);
 94                 double ans = sqrt((h-zz)*(h-zz)+res*res);
 95                 printf("%.2lf\n",ans);
 96             }
 97             else if(dot_online(newp,ll1,ll2))
 98             {
 99                 double ans = fabs(h-zz);
100                 printf("%.2lf\n",ans);
101             }
102             else
103             {
104                 point pseg = ptoseg(newp,ll1,ll2);
105                 double res = distancen(pseg,newp);
106                 double ans = sqrt(res*res+(zz-h)*(zz-h));
107                 printf("%.2lf\n",ans);
108             }
109         }
110     }
111     return 0;
112 }

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:1557 热浪

下一篇:bzoj2982 -- Lucas定理