推公式hdu2298

(0,0)点到(x,y)以v射箭 问 最小的角度 

不能射到 -1

x=v*cos(a)*t;

y=v*sin(a)*t-0.5*g*t*t;

消去t;

y=x*tan(a)-0.5*g*x*x/(v*v*cos(a)*cos(a));

v*v*y=v*v*x*tan(a)-0.5*g*x*x*sec(a)*sec(a);

根据 1+tan(a)*tan(a)=sec(a)*sec(a);

化简得到 g*x*x*tan(a)*tan(a)-2*x*v*v*tan(a)+2*v*v*y+g*x*x=0;

然后二元一次方程

几个特判一下

a=g*x*x;   a!=0     所以x要判

然后b*b-4*a*c;

然后解中找小的但是>=0

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>

using namespace std;
typedef long long ll;
#define MAXN 100010
#define g   9.8
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        double x,y,v,a,b,c,d,x1,x2;
        scanf("%lf%lf%lf",&x,&y,&v);
        if(x==0)
        {
            if(y==0)
                printf("%.6lf
",0);
            else
            {
                double s1=v*v/(2*g);
                if(s1>=y)
                    printf("%.6lf
",90);
                else
                    printf("-1
");
            }
            continue;
        }
        a=g*x*x;
        b=(-2)*x*v*v;
        c=2*v*v*y+g*x*x;
        if(b*b-4*a*c<0)
        {
            printf("-1
");
            continue;
        }
        d=sqrt(b*b-4*a*c);
        x1=(-b-d)/(2*a);
        x2=(-b+d)/(2*a);
        if(x1>=0)
            printf("%.6lf
",atan(x1));
        else if(x2>=0)
            printf("%.6lf
",atan(x2));
        else
            printf("-1
");
    }
    return  0;
}
原文地址:https://www.cnblogs.com/cherryMJY/p/6242708.html