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 }