刚开始想用二分去做,却没有证明单调性
如果非要用二分做,应该先用三分找到最顶端的点,然后再二分,这样太麻烦了,
其实,可以一个公式搞定
y=x*tanα-gx*x/(2*v*v*(cosα)*(cosα))
相信这一步大家都能推出来,然后问题来了
1/(cosα*cosα),1等于sinα^2 + cosα^2
那么1/(cosα*cosα)就到等于(sinα^2 + cosα^2)/( cosα^2)
也就是1+tanα^2
所以式子可以化成关于tanα的方程
解出来,然后直接用atan函数得到角度完美解决
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int MX = 20 + 5;
const int INF = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double exps = 1e-8;
int main() {
int T;
scanf("%d", &T);
while(T--) {
double x, y, v, g = 9.8;
scanf("%lf%lf%lf", &x, &y, &v);
double A, B, C, D, P1, P2;
if(v < exps) {
printf("-1\n");
break;
}
A = -g * x * x / (2.0 * v * v);
B = x;
C = -y + A;
D = B * B - 4 * A * C;
if(D < 0) {
printf("-1\n");
continue;
}
if(fabs(x) < exps) {
//说明x等于0
double h = v * v / (2 * g);
if(y <= h) printf("%.6lf\n", pi / 2);
else printf("-1\n");
continue;
}
D = sqrt(D);
P1 = (-B - D) / (2.0 * A);
P2 = (-B + D) / (2.0 * A);
P1 = atan(P1);
P2 = atan(P2);
double ans = 100;
if(0 <= P1 && P1 <= pi / 2 && P1 < ans) {
ans = P1;
}
if(0 <= P2 && P2 <= pi / 2 && P2 < ans) {
ans = P2;
}
if(ans > 99) {
printf("-1\n");
} else {
printf("%.6lf\n", ans);
}
}
return 0;
}