现在只用公式算出,二分三分没有尝试,解出来了便会上传
公式法:
有题目可以知道:x,y,v都是已知条件
设vx=v*cos(α),vy=v*sin(α),同时从P(0,0)点到达目标点花了t时间,重力加速度为G=9.8.
∴x=vx*t,y=vy*t-1/2*G*t2.
消掉vx,vy,t可以转换为y=v*sin(α)*x/cos(α)-1/2*g*x2/(v2*cos(α)2).
∴将sin(α)/cos(α)=tan(α);
∴y=v*x*tan(α)-(1/2*g*x2/v2)*((sin(α)2+cos(α)2)/cos(α)2);
∴y=v*x*tan(α)-(1/2*g*x2/v2)*(1+tan(α)2);
∴将其进行整理可以得到:g*x2*tan(α)2-2*v2*x*tan(α)+2*v2y+g*x2=0;
∴可以得到△=b2-4*a*c;
∴令a=g*x2,b=-2*v2*x,c=2*v2y+g*x2.
又∵x1=(-b+(b2-4*a*c)?)/(2*a),x2=(-b-(b2-4*a*c)?)/(2*a).
∴可以通过上述公式将tan(α)求出,然后就是通过atan((tan(α)))将α求出
接着检查α是否符合条件就可以了。
/*
Author: 2486
Memory: 1616 KB Time: 0 MS
Language: C++ Result: Accepted
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const double PI=acos(-1);
const double G=9.8;
int T;
double x,y,v;
int main() {
scanf("%d",&T);
while(T--) {
scanf("%lf%lf%lf",&x,&y,&v);
double a=G*x*x,b=-2.0*v*v*x,c=2.0*v*v*y+G*x*x;
double posi=(-b+sqrt(b*b-4.0*a*c))/2.0/a;
double ne=(-b-sqrt(b*b-4.0*a*c))/2.0/a;
posi=atan(posi),ne=atan(ne);
if(posi>=0&&posi<=PI/2.0&&ne>=0&&ne<=PI/2.0) {
printf("%.6lf\n",posi>ne?ne:posi);
} else if(ne>=0&&ne<=PI/2.0) {
printf("%.6lf\n",ne);
} else if(posi>=0&&posi<=PI/2.0) {
printf("%.6lf\n",posi);
} else printf("-1\n");
}
return 0;
}
三分二分方法
/*
Author: 2486
Memory: 1628 KB Time: 0 MS
Language: C++ Result: Accepted
*/
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const double PI=acos(-1);
const double eps=1e-10;
int T;
double x,y,v;
double C(double m) {
double vx=v*cos(m),vy=v*sin(m);
return (vy*x)/vx-9.8*(x/vx*x/vx)/2.0;
}
bool B(double m) {
double vx=v*cos(m),vy=v*sin(m);
return (vy*x)/vx-9.8*(x/vx*x/vx)/2.0>=y;
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%lf%lf%lf",&x,&y,&v);
double lb=0,ub=PI/2.0;
///////////////求出最大高度所对应的倾斜度////////////////
while(ub-lb>eps) {
double mid=(ub+lb)/2.0;
double mmid=(ub+mid)/2.0;
if(C(mid)>C(mmid)) {
ub=mmid;
} else lb=mid;
}
if(C(ub)<y) {
printf("-1\n");
continue;
}
///////////////////////////////
lb=0;
////////////////求出无限接近目标的倾斜度///////////////
while(ub-lb>eps) {
double mid=(ub+lb)/2.0;
if(B(mid)) {
ub=mid;
} else lb=mid;
}
///////////////////////////////
printf("%.6lf\n",ub);
}
return 0;
}