【三分+精度问题】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
",ans);
71         }
72     }
73     return 0;
74 }
View Code
原文地址:https://www.cnblogs.com/itcsl/p/7192935.html