【三分+精度问题】G. Toxophily
https://www.bnuoj.com/v3/contest_show.php?cid=9154#problem/G
【题意】
已知人的坐标在(0,0),靶的位置在(x,y),人以速度v射箭并且射中靶,求v与x的夹角。
【思路】
- 经典的三分+二分题
- 先三分求出纵坐标最大时的sita,如果这时的纵坐标都小于y,就输出-1
- 三分确定sita后,在二分求出正解
- 这道题我的代码eps=1e-9才能过
【Accepted】
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<algorithm> 6 #include<cmath> 7 8 using namespace std; 9 const double pi=acos(-1.0); 10 double x,y,v,sita; 11 const double eps=1e-8; 12 const double G=9.8; 13 double calc(double ang) 14 { 15 double t=x/(v*cos(ang)); 16 return v*sin(ang)*t-0.5*G*t*t; 17 } 18 double triplediv() 19 { 20 double l=0.0; 21 double r=0.5*pi; 22 while(r-l>eps) 23 { 24 double mid1=(2*l+r)/3.0; 25 double mid2=(l+2*r)/3.0; 26 if(calc(mid1)<calc(mid2)) 27 { 28 l=mid1+eps; 29 } 30 else 31 { 32 r=mid1-eps; 33 } 34 } 35 sita=l; 36 return calc(l); 37 } 38 39 double doublediv() 40 { 41 double l=0;double r=sita; 42 while(r-l>eps) 43 { 44 double mid=(l+r)/2.0; 45 if(calc(mid)<y) 46 { 47 l=mid+eps; 48 } 49 else 50 { 51 r=mid-eps; 52 } 53 } 54 return l; 55 } 56 int main() 57 { 58 int T; 59 scanf("%d",&T); 60 while(T--) 61 { 62 scanf("%lf%lf%lf",&x,&y,&v); 63 if(triplediv()<y) 64 { 65 puts("-1"); 66 } 67 else 68 { 69 double ans=doublediv(); 70 printf("%.6f\n",ans); 71 } 72 } 73 return 0; 74 }