HDU 2298 Toxophily 【三分算法 or 直接推导物理公式】

http://acm.hdu.edu.cn/showproblem.php?pid=2298

题目大意:Bob在(00)点想射在(x, y)点的水果,初始的速度为v(已知), g=9.8, 求最小的角度射到苹果

解题思路:

---直接推到物理公式:

将速度的分解为x方向和y方向,然后列出式子

1> x=vcosθ* t   ----变形---> t=x/vcosθ

2> y=vsinθ*t -g*t*t/2 

t的函数带入2>式中得  y=tanθ* x-g*x*x/(2*v*v*cos^2θ)  ---3

1/cos^2θ=(sin^2θ+cos^2θ)/cos^2θ= 1+tan^2θ ----带入3式中,得:

g*x*x*tan^2θ-2*v*v*x*tanθ+g*x*x+2*v*v*y=0

tanθ看成是未知数,那么a=g*x*x, b=-2*v*v*x, c=2*v*v*y+g*x*x;

Δ=b^2-4ac 先进行判断是否有根。如果没有根输出-1,否则根据求根公式

X1=[-b+Δ^(1/2)]/2a

X2=[-b-Δ^(1/2)]/2a

如果求的解不在[0. Π/2]内还是算无解。

代码如下:

 

View Code
/*
直接推导物理公式

*/

#include<stdio.h>
#include<math.h>
#define pi acos(-1)
#define g 9.8
int main()
{
    int T;
    double x, y, v;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%lf%lf%lf", &x, &y, &v);
        double dd, x1, x2, a, b, c;
        a=g*x*x, b=-2*v*v*x, c=2*v*v*y+g*x*x;
        dd=b*b-4*a*c;
        if(dd<0)
            printf("-1\n");
        else
        {
            x1=atan((-1*b+sqrt(dd))/(2*a));
            x2=atan((-1*b-sqrt(dd))/(2*a));
            if((x1<0||x1>pi/2)&&(x2<0||x2>pi/2))
                printf("-1\n");
            else if(x1<0||x1>pi/2)
                printf("%.6lf\n", x2);
            else if(x2<0||x2>pi/2)
                printf("%.6lf\n", x1);
            else
                printf("%.6lf\n", x1>x2?x2:x1);
        }
    }
    return 0;
}

 

---三分+二分算法

--三分+二分算法

问题1》三分什么变量满足凸(凹)型函数?目的三分出什么结果

问题2cal()里面的公式放什么,怎么推到的?

我们可以知道当θ变幻时,落在横坐标为x处的y点左边是变化的,而且呈凸形变化(我不知道怎么去证明),因此三分的对象就是θ,三分出的结果就是找出很逼近y值的角度θ。

cal()函数放的就该是根据θ,求的的y’的值,物理公式推导出y=x*tan(θ)-g*x*x/(2*v*v*cos(θ)*cos(θ));

 

double cal(double t)

{

    return x*tan(t)-g*x*x/(2*v*v*cos(t)*cos(t));

}

PS:不得不承认画图能力很差。

然后求出的θ还要进行二分它,因为这个θ就相当于A点附近的点,即f(θ)>=y,我们从[0, θ]进行二分求出一个很接近f(θ1)~~y的θ1即相当于图中的B点。

三分+二分算法代码如下:

View Code
原文地址:https://www.cnblogs.com/Hilda/p/2939797.html