大意:中文题,很好理解,搞清楚各种变量就行。
思路:我知道的好像有两种解法,一种是求土匪的头心与子弹射出的直线求点到直线距离,在判断一下方向对不对;另一种是求出子弹射出点与土匪头心连线,求出子弹的射出的直线,求两直线的夹角, 求出子弹射出点与土匪头心连线,求出求出子弹射出点与土匪头的切线,求两直线的夹角,比较这两个夹角的大小判断是不是会打到。
这里我用第一种方法过的,就贴第一种的吧。
1 struct point 2 { 3 double x, y, z; 4 } A, B, C; 5 6 ///计算cross product U x V 7 point xmult(point u,point v){ 8 point ret; 9 ret.x=u.y*v.z-v.y*u.z; 10 ret.y=u.z*v.x-u.x*v.z; 11 ret.z=u.x*v.y-u.y*v.x; 12 return ret; 13 } 14 15 ///两点距离,单参数取向量大小 16 double Distance(point p1,point p2){ 17 return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)+(p1.z-p2.z)*(p1.z-p2.z)); 18 } 19 20 ///矢量差 U - V 21 point subt(point u,point v){ 22 point ret; 23 ret.x=u.x-v.x; 24 ret.y=u.y-v.y; 25 ret.z=u.z-v.z; 26 return ret; 27 } 28 29 ///向量大小 30 double vlen(point p){ 31 return sqrt(p.x*p.x+p.y*p.y+p.z*p.z); 32 } 33 34 double ptoline(point p,point l1,point l2){ 35 return vlen(xmult(subt(p,l1),subt(l2,l1)))/Distance(l1,l2); 36 } 37 38 int n; 39 double h1,r1; 40 double h2,r2,x3,y3,z3; 41 42 void Solve() 43 { 44 scanf("%d", &n); 45 while(n--) 46 { 47 scanf("%lf%lf%lf%lf%lf", &h1, &r1, &A.x, &A.y, &A.z); 48 scanf("%lf%lf%lf%lf%lf%lf%lf%lf", &h2, &r2, &B.x, &B.y, &B.z, &C.x, &C.y, &C.z); 49 50 A.z = A.z+h1-r1; 51 B.z = B.z+h2*0.9-r2; 52 53 double x = A.x-B.x; 54 double y = A.y-B.y; 55 double z = A.z-B.z; 56 //printf("%lf %lf %lf ", x, y, z); 57 58 point D; 59 60 D.x = C.x+B.x; 61 D.y = C.y+B.y; 62 D.z = C.z+B.z; 63 64 double d = ptoline(A, B, D); 65 //printf("%lf ", d); 66 67 if(d <= r1 && (x*C.x+y*C.y+z*C.z > 0)) 68 { 69 printf("YES "); 70 } 71 else 72 { 73 printf("NO "); 74 } 75 } 76 }