题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1174
解题报告:就是用到了三维向量的点积来求点到直线的距离,向量(x1,y1,z1)与(x2,y2,z2)的点积是:x1*x2+y1*y2+z1*z2.
然后要注意的就是当两个向量的夹角大于等于90度时,无论如何都不能射中.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const double PI = acos(-1.0); 8 struct Point 9 { 10 double x,y,z; 11 Point(double a = 0,double b = 0,double c = 0) :x(a),y(b),z(c) {} 12 friend Point operator + (Point a,Point b) 13 { 14 return Point(a.x+b.x,a.y+b.y,a.z+b.z); 15 } 16 friend Point operator - (Point a,Point b) 17 { 18 return Point(a.x-b.x,a.y-b.y,a.z-b.z); 19 } 20 }; 21 double length(Point a) 22 { 23 return sqrt(a.x*a.x+a.y*a.y+a.z*a.z); 24 } 25 int main() 26 { 27 // freopen("in","r",stdin); 28 int T; 29 double h1,r1,h2,r2; 30 Point p1,p2,p; 31 scanf("%d",&T); 32 while(T--) 33 { 34 scanf("%lf%lf%lf%lf%lf",&h1,&r1,&p1.x,&p1.y,&p1.z); 35 scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&h2,&r2,&p2.x,&p2.y,&p2.z,&p.x,&p.y,&p.z); 36 Point o1 = p2,o2 = p1; 37 o2.z += (h1 - r1); 38 o1.z += (0.9 * h2 - r2); 39 Point oo = o2 - o1; 40 double temp = (oo.x*p.x + oo.y * p.y + oo.z * p.z) / length(oo) / length(p); 41 double angle = acos(temp); //求夹角 42 if(angle <= 0) 43 { 44 puts("NO"); 45 continue; 46 } 47 double D = sin(angle) * length(oo); 48 printf(D <= r1? "YES ":"NO "); 49 } 50 return 0; 51 }