首页 > 代码库 > 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射气球
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。