hdu 2298 Toxophily 公式 或者 三分+二分。

来源:互联网 发布:ceph 无法写入数据 编辑:程序博客网 时间:2024/05/21 19:42

射箭 为射到靶子的最小出手角度。 出手速度  、靶子的位置 给出。

公式推导。

三角函数 推导 求解。


最终公式

  sin(2*p -q ) = (g*a*a + b)/(v*v * sqrt(a*a + b*b))

a , b 为靶子的坐标 v是出手速度。

p 要求的角度

cos q = a/ sqrt(a*a + b*b);



#include <iostream>#include <cstdio>#include <cmath>using namespace std;const double g = 9.8;double a,b,v;void solve(){    double ans = g*a*a/(v*v)+b;    ans/= sqrt(a*a+b*b);    if(ans >=1){        cout << "-1"<<endl;        return;    }    double  k = acos(a/sqrt(a*a+b*b));    double s = asin(ans);    s= (s+k)/2;    printf("%.6f\n",s);     }int main(){    int t ;    cin >>t ;    while(t--){        scanf("%lf%lf%lf",&a,&b,&v);        solve();    }    return 0;}

也可以三分+ 二分做。


三分精度一直是个问题。 精度卡了一会。

在上凸曲线上找一个 点y 对应的x 。先三分找到 最高点, 再在 0 和最高点之间二分求解。


#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <stack>#include <cstring>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>#include <assert.h>#include <queue>#define REP(i,n) for(int i=0;i<n;i++)#define TR(i,x) for(typeof(x.begin()) i=x.begin();i!=x.end();i++)#define ALLL(x) x.begin(),x.end()#define SORT(x) sort(ALLL(x))#define CLEAR(x) memset(x,0,sizeof(x))#define FILLL(x,c) memset(x,c,sizeof(x))using namespace std;const double eps = 1e-9;#define LL long long #define pb push_backconst double g = 9.8;double a,b,v;double f(double aa){    return  a*tan(aa) - g*a*a/(2*v*v*cos(aa)*cos(aa));}const double PI = acos(-1.0);void solve(){     double left = 0;     double right = PI/2;     while(right - left > 1e-9){       double lmid = (left + right)/2;       double rmid = (lmid + right)/2;       if(f(lmid ) < f(rmid)){             left = lmid ;       }else{               right = rmid;       }     }     if( f(left) < b){        cout << "-1"<<endl;        return ;     }     double l = 0;     double r = left;     while(r-l>1e-9){          double mid = (l+r)/2;          if(f(mid)<=b){           l = mid;          }else{           r = mid;          }     }     printf("%.6f\n",l);}int main(){    int t ;    cin >>t ;    while(t--){    scanf("%lf%lf%lf",&a,&b,&v);    solve();    }    return 0;}




原创粉丝点击