首页 > 代码库 > tmk射气球

tmk射气球

题目描述

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

输入

第一行一个整数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] 

输出

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

样例输入

1

1 1 1 2 2

0 0 0 4 4 4

2

0

3

样例输出

1.73

17.92

解题思路:

这题只要细心些就能写,首先先判断线段是否为一个点,若是,直接求两点距离,若不是,在判断这个点能否和线段构成锐角三角形,若能,求出这个三角形的高,即为解,若不能,线段两端点到这点的最短距离即为解。

代码如下:

 

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<math.h>
  4 int main()
  5 {
  6     int a,i,c,t,n;
  7     double h,x1,y1,x2,y2,x,y,z,zz,xx,yy;//输入的数据 
  8     double aa,bb,cc,dd,s,q,max,k,x0,y0,b1,b2;//aa,bb,cc,dd分别为构成的三角形的三条边长和高 
  9     scanf("%d",&a);
 10     while(a--)
 11     {
 12         scanf("%lf%lf%lf%lf%lf",&h,&x1,&y1,&x2,&y2);
 13         scanf("%lf%lf%lf%lf%lf%lf",&xx,&yy,&zz,&x,&y,&z);
 14         scanf("%d",&n);
 15         while(n--)
 16         {
 17             scanf("%d",&t);
 18             if(x1==x2&&y1==y2)//若线段为点,直接求出两点距离 
 19             {
 20                 printf("%.2lf\n",sqrt((xx+x*t-x1)*(xx+x*t-x1)+(yy+y*t-y1)*(yy+y*t-y1)+(zz+z*t-h)*(zz+z*t-h)));
 21                 continue;
 22             }
 23             aa=sqrt((xx+x*t-x1)*(xx+x*t-x1)+(yy+y*t-y1)*(yy+y*t-y1)+(zz+z*t-h)*(zz+z*t-h));
 24             bb=sqrt((xx+x*t-x2)*(xx+x*t-x2)+(yy+y*t-y2)*(yy+y*t-y2)+(zz+z*t-h)*(zz+z*t-h));
 25             cc=sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
 26             q=(aa+bb+cc)/2;
 27             s=sqrt(q*(q-aa)*(q-bb)*(q-cc));//海伦公式求三角形面积 
 28             dd=s*2/cc;//求高 
 29             if(x1==x2)//若平行y轴 
 30             {
 31                 if(yy+y*t>=y1&&yy+y*t<=y2||yy+y*t>=y2&&yy+y*t<=y1)
 32                 {
 33                     max=(bb-aa>1e-10)?aa:bb;
 34                     max=(max-dd>1e-10)?dd:max;
 35                     printf("%.2lf\n",max);
 36                     continue;
 37                 }
 38                 else
 39                 {
 40                     max=(bb-aa>1e-10)?aa:bb;
 41                     printf("%.2lf\n",max);
 42                     continue;
 43                 }
 44             }
 45             else if(y1==y2)//平行x轴 
 46             {
 47                 if(xx+x*t>=x1&&xx+x*t<=x2||xx+x*t>=x2&&xx+x*t<=x1)
 48                 {
 49                     max=(bb-aa>1e-10)?aa:bb;
 50                     max=(max-dd>1e-10)?dd:max;
 51                     printf("%.2lf\n",max);
 52                     continue;
 53                 }
 54                 else
 55                 {
 56                     max=(bb-aa>1e-10)?aa:bb;
 57                     printf("%.2lf\n",max);
 58                     continue;
 59                 }
 60             }
 61             else
 62             {
 63                 k=-(1/((y2-y1)/(x2-x1)));//求垂直于线段的直线斜率 
 64                 b1=y1-k*x1;//垂直于线段且过端点的截距 
 65                 b2=y2-k*x2;//垂直于线段且过端点的截距 
 66                 if((x1>x2&&y1<y2)||(x1<x2&&y1>y2))
 67                 {
 68                     if(((yy+y*t)>=(k*(xx+x*t)+b1))&&((yy+y*t)<=(k*(xx+x*t)+b2))||((yy+y*t)<=(k*(xx+x*t)+b1))&&((yy+y*t)>=(k*(xx+x*t)+b2)))
 69                     {
 70                         max=(bb-aa>1e-10)?aa:bb;
 71                         max=(max-dd>1e-10)?dd:max;
 72                         printf("%.2lf\n",max);
 73                         continue;
 74                     }
 75                     else
 76                     {
 77                         max=(bb-aa>1e-10)?aa:bb;                        
 78                         printf("%.2lf\n",max);
 79                         continue;
 80                     }
 81                 }
 82                 else
 83                 {
 84                     if(((yy+y*t)>=(k*(xx+x*t)+b1))&&((yy+y*t)<=(k*(xx+x*t)+b2))||((yy+y*t)<=(k*(xx+x*t)+b1))&&((yy+y*t)>=(k*(xx+x*t)+b2)))
 85                     {
 86                         max=(bb-aa>1e-10)?aa:bb;
 87                         max=(max-dd>1e-10)?dd:max;
 88                         printf("%.2lf\n",max);
 89                         continue;
 90                     }
 91                     else
 92                     {
 93                         max=(bb-aa>1e-10)?aa:bb;                        
 94                         printf("%.2lf\n",max);
 95                         continue;
 96                     }
 97                 }        
 98             }
 99         }
100     }
101     return 0;
102  } 

 

tmk射气球