description
NPY is going to have a PE test.One of the test subjects is throwing the shot.The height of NPY is H meters.He can throw the shot at the speed of v0 m/s and at the height of exactly H meters.He wonders if he throws the shot at the best angle,how far can he throw ?(The acceleration of gravity, g, is 9.8m/s29.8m/s2)
Input
The first line contains a integer T(T≤10000)T(T≤10000),which indicates the number of test cases.
The next T lines,each contains 2 integers H(0≤h≤10000m)H(0≤h≤10000m),which means the height of NPY,and v0(0≤v0≤10000m/s)v0(0≤v0≤10000m/s), which means the initial velocity.
Output
For each query,print a real number X that was rounded to 2 digits after decimal point in a separate line.X indicates the farthest distance he can throw.
Sample
Input
2
0 1
1 2
Output
0.10
0.99
题意:
给定初始高度y和初速度v,求某一角度抛出下沿x轴移动的最短距离
分析:
先进行公式推算,得出其函数为凸函数,利用三分枚举角度,根据物理公式求出距离
问题:
将角度三等分时会陷入死循环,暂未解决
代码:
#include<iomanip>
#include<iostream>
#include<cmath>
#include<algorithm>
#define PI acos(-1)
using namespace std;double Func(int y, double v, double angle)
{
double g = 9.8;
double Vx = v*cos(angle);
double Vy = v*sin(angle);
double up_t = Vy / g; //上升时间
double x = Vx*up_t; //上升时间沿x轴运动的距离
double H = y*1.0 + 0.5*g*up_t*up_t; //总高度
double down_t = sqrt(2.0*H / g); //下降时间
x += Vx*down_t; //上升时间沿x轴运动的距离+下降时间沿x轴运动的距离
return x;
}
double solve(int y, double v)
{
double left = 0.0;
double right = (PI*1.0) / 2;
double lmid, rmid;
while (right - left > 1e-8)
{
lmid = (left + right) / 2.0;
rmid = (lmid + right) / 2.0;
if (Func(y, v, lmid) > Func(y, v, rmid))
right = rmid;
else
left = lmid;
}
return Func(y, v, left);
}
int main()
{
int T;
int y;
double v;
cin >> T;
while (T--)
{
cin >> y >> v;
cout << setiosflags(ios::fixed) << setprecision(2) << solve(y, v) << endl;
}
return 0;
}