hdu 4024 二分

转自:http://www.cnblogs.com/kuangbin/archive/2012/08/23/2653003.html
 
一种是直接根据公式计算的,另外一种是二分算出来的。两种方法速度都很快,充分体会到二分的效率之高啊~~~
 
题目中一个很重要的条件就是 (Lx*Lx+Ly*Ly) < vD*vD < vB*vB ,
这样说明一定是可以追上的,而且可以以最大的距离射中,所以第一问的答案一定就是L的。
假设追击者跑的时间是 t1,那么肯定子弹飞行时间就是 L/vB 了
那么此时被追击者的位置就是 A(x1+(t1+L/vB)*Lx,y1+(t1+L/vB)*Ly )了
那么 点 (x2,y2) 到点A的距离等于 L+vD*t1  或者是 L-vD*t1  //两个方程
联立一个一元二次方程,很容易解出来。上面有两个方程,可以求得4个解。
那么选择其中最小的非负解就是答案了。
注意最后时间要加上  L/vB
 1 /*
 2 HDU 4024
 3 找数学公式计算
 4 */
 5 
 6 #include<stdio.h>
 7 #include<iostream>
 8 #include<math.h>
 9 #include<string.h>
10 using namespace std;
11 
12 int main()
13 {
14     //freopen("D.in","r",stdin);
15     //freopen("D.out","w",stdout);
16     double x1,y1,x2,y2,Lx,Ly,vD,vB,L;
17     while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&Lx,&Ly,&vD,&vB,&L))
18     {
19         if(x1==0&&y1==0&&x2==0&&y2==0&&Lx==0&&Ly==0&&vD==0&&vB==0&&L==0)break;
20         double a=vD*vD-Lx*Lx-Ly*Ly;
21         double b=2*L*vD-2*Lx*(x1-x2+L*Lx/vB)-2*Ly*(y1-y2+L*Ly/vB);
22         double c=L*L-(x1-x2+L*Lx/vB)*(x1-x2+L*Lx/vB)-(y1-y2+L*Ly/vB)*(y1-y2+L*Ly/vB);
23 
24         double s1=(-b-sqrt(b*b-4*a*c))/(2*a);
25         double s2=(-b+sqrt(b*b-4*a*c))/(2*a);
26 
27         b=-2*L*vD-2*Lx*(x1-x2+L*Lx/vB)-2*Ly*(y1-y2+L*Ly/vB);
28         double s3=(-b-sqrt(b*b-4*a*c))/(2*a);
29         double s4=(-b+sqrt(b*b-4*a*c))/(2*a);
30 
31         printf("%.3lf ",L);
32 //从s1 s2 s3 s4当中选出一个最小的正数
33         if(s1<0)s1=10000000000.0;
34         if(s2<0)s2=10000000000.0;
35         if(s3<0)s3=10000000000.0;
36         if(s4<0)s4=10000000000.0;
37         printf("%.3lf\n",min(s1,min(s2,min(s3,s4)))+L/vB);//不要忘记加上L/vB
38     }
39     return 0;
40 }

 

 1 /*
 2 HDU 4024
 3 二分
 4 */
 5 #include<stdio.h>
 6 #include<iostream>
 7 #include<math.h>
 8 #include<algorithm>
 9 using namespace std;
10 const double eps=1e-8;//1e-6会WR
11 const double INF=1e9;
12 int main()
13 {
14     //freopen("D.in","r",stdin);
15     //freopen("D.out","w",stdout);
16     double x1,y1,x2,y2,Lx,Ly,vD,vB,L;
17     while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&Lx,&Ly,&vD,&vB,&L))
18     {
19         if(x1==0&&y1==0&&x2==0&&y2==0&&Lx==0&&Ly==0&&vD==0&&vB==0&&L==0)break;
20         double l=0;
21         double r=INF;
22         double mid;
23         double x,y;
24         while(l<r-eps)
25         {
26             mid=(l+r)/2;
27             x=x1+mid*Lx;
28             y=y1+mid*Ly;
29             double d=sqrt((x-x2)*(x-x2)+(y-y2)*(y-y2));//两点距离
30             double d1=vD*(mid-L/vB);//勇士跑的最大距离
31             if(d<=L)//在圆里面  平行关系
32             {
33                 if(d+d1<=L)l=mid;//到不了圆周上
34                 else r=mid;
35             }
36             else
37             {
38                 if(L+d1<=d)l=mid;//到不了圆周上
39                 else r=mid;
40             }
41         }
42         printf("%.3lf %.3lf\n",L,mid);
43     }
44     return 0;
45 }

 

posted @ 2015-03-07 10:27  miao_a_miao  阅读(116)  评论(0编辑  收藏  举报