【hdu2298】【三分】Toxophily

来源:互联网 发布:本地连接阿里云数据库 编辑:程序博客网 时间:2024/05/16 05:20

题目链接【hdu2298】

题目大意

建立一个二维坐标系,给你一个向上速度V,让你求出最小的角度使得你射出的箭能够到达给定的点(x,y)。如果不能输出为-1,如果能到达,输出最小的角度
总共T组数据
每组数据给定三个数 X, Y, V
T ≤ 100.
0 ≤ x, y, v ≤ 10000.

思路

首先这题是一道物理题,需要我们根据题意抽象一个函数出来。对物体的运动作分解后,可以得到:
f(t)=x*tan(t)-g*x*x/(v*cos(t))^2/2,其中t表示v与x轴正向的夹角(弧度),f(t)表示物体的运动轨迹与直线x0=x的交点纵坐标。
分析后可以得到该函数在区间(0,π/2)上先增后减,所以我们可以在该区间上三分,求出使函数取得极大值的角度t0。若f(t0)< y,则无解;否则对区间(0,t0)二分,找到使得f(t)=y的t值,即为所求。

代码

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <cstdlib>#include <iomanip>#include <cmath>#define eps 1e-9 #define g 9.8using namespace std;const double pi=acos(-1.0);double x,y,v;inline double qf(double t){    return x*tan(t)-g*x*x/2/(v*v*cos(t)*cos(t));}int main(){    int T;    scanf("%d",&T);    while(T--){        scanf("%lf%lf%lf",&x,&y,&v);        double mid1,mid2,l=0,r=pi/2,mid;        while(l<r-eps){            mid1=(2*l+r)/3;            mid2=(l+2*r)/3;            if(qf(mid1)<qf(mid2)) l=mid1;            else r=mid2;        }        double mi=(mid1+mid2)/2;        if(qf(mi)<y)printf("-1\n");        else{            l=0;r=mi;            while(l<r-eps){                mid=(l+r)/2;                if(qf(mid)<y)l=mid;                else r=mid;            }            printf("%.6lf\n",mid);        }    }    return 0;}

…就是这样了

原创粉丝点击