Toxophily HDU - 2298 三分+二分

代码+解析:

 1 //题意:
 2 //有一个大炮在(0,0)位置,为你可不可以把炮弹射到(x,y)这个位置
 3 //题目给你炮弹初始速度,让你求能不能找出来一个炮弹射出时角度满足题意
 4 //题解:
 5 //由物理公式分析可知:
 6 //Vx=v*cos(a)
 7 //Vy=v*sin(a)
 8 //t=x/Vx=x/(v*cos(a))
 9 //y=-(1/2)*g*t*t+Vy*t=-(1/2)*g*t*t+v*sin(a)*t
10 //一看是一个一元二次函数那他的图像不是先减后增就是先增后减。那就用三分找出来它的最高位置对应度数是多少(假设是ans)
11 //那么(0,ans)与(ans,90)这两个区间所对应曲线肯定一致,那我们就挑一个区间进行二分查找答案就完了
12 #include<stdio.h>
13 #include<stdlib.h>
14 #include<iostream>
15 #include<string.h>
16 #include<algorithm>
17 #include<math.h>
18 using namespace std;
19 const int maxn=500005;
20 const int INF=0x3f3f3f3f;
21 #define eps 1e-11
22 #define PI acos(-1.0)  //180度的弧度值
23 typedef long long ll;
24 double x,y,v;
25 double f(double a)  //求大炮角度为a时,大炮能射多高
26 {
27     double t = x/(v*cos(a));
28     return v*sin(a)*t - 9.8/2.0*t*t;
29 }
30 int main()
31 {
32     int t;
33     scanf("%d",&t);
34     while(t--)
35     {
36         scanf("%lf%lf%lf",&x,&y,&v);
37         double l=0,r=PI/2,m1,m2;   //先找出来大炮的能射最高所对应的角度,只需要在(0,90)度范围内找就行了
38         while(r-l>eps)
39         {
40             m1=(l+r)/2;
41             m2=(m1+r)/2;
42             if(f(m1)<f(m2))
43                 l=m1;
44             else r=m2;
45         }
46         if(f(l)<y)  //如果大炮最高也不到y,那就根本无法打到那个位置
47         {
48             printf("-1\n");
49             continue;
50         }
51         double mid,ll=0,rr=l;
52         while(rr-ll>eps)  //找到之后在二分出来那个角度能刚好射到高度为y
53         {
54             mid=(ll+rr)/2;
55             if(f(mid)<y)
56                 ll=mid;
57             else rr=mid;
58         }
59         printf("%.6lf\n",ll);
60     }
61     return 0;
62 }

 

posted @ 2019-11-15 17:17  kongbursi  阅读(144)  评论(0编辑  收藏  举报