Toxophily Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Now given the object's coordinates, please calculate the angle between the arrow and x-axis at Bob's point. Assume that g=9.8N/m. ios
已知发射点坐标为(0,0)和重力加速度g=9.8,给出目标的坐标和初速度。求能够击中目标的最小仰角。有两种思路。第一种是直接若是能够击中目标。写出公式,化成一元二次方程,把公式内的三角函数全部化成tan,推断[0。PI/2]有无解;另一种方法就是三分+二分。首先三分仰角,求出轨迹在x处的纵坐标最大值。若纵坐标最大值小于y,则直接输出-1,三分事后[0,r]上就是单调递增的,直接二分就能够。git
#include<stack>//推导公式 #include<queue> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #pragma commment(linker,"/STACK: 102400000 102400000") #define mset0(t) memset(t,0,sizeof(t)) #define lson a,b,l,mid,cur<<1 #define rson a,b,mid+1,r,cur<<1|1 using namespace std; const double PI=3.141592653; const double eps=1e-8; const int MAXN=500020; const double g=9.8; double x,y,v,ans; int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif // ONLINE_JUDGE int tcase; scanf("%d",&tcase); while(tcase--) { scanf("%lf%lf%lf",&x,&y,&v); /*if(x==0||y==0) //这个if语句主要是用来特判0 50 10000这样的数据的。但不知道为何去掉这个也能AC { if(x==0&&y==0) printf("0.000000\n"); else if(y==0) printf("-1\n"); else if(v*v*0.5/g>=y) printf("%.6lf\n",PI/2); else printf("-1\n"); continue; }*/ ans=3; double a=g*x*x; double b=-2*v*v*x; double c=2*v*v*y+g*x*x; double der=b*b-4*a*c; if(der<0) { printf("-1\n"); continue; } double ans1=atan((-b-sqrt(der))/(2*a)); double ans2=atan((-b+sqrt(der))/(2*a)); if(ans1>=0&&ans1<=PI/2) ans=min(ans,ans1); if(ans2>=0&&ans2<=PI/2) ans=min(ans,ans2); printf("%.6lf\n",ans); } return 0; }
#include<stack>//三分+二分代码 #include<queue> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #pragma commment(linker,"/STACK: 102400000 102400000") #define mset0(t) memset(t,0,sizeof(t)) #define lson a,b,l,mid,cur<<1 #define rson a,b,mid+1,r,cur<<1|1 using namespace std; const double PI=3.141592653; const double eps=1e-8; const int MAXN=500020; const double g=9.8; double x,y,v,ans; double geth(double r) { return (v*sin(r))*(x/(v*cos(r)))-0.5*g*(x/(v*cos(r)))*(x/(v*cos(r))); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif // ONLINE_JUDGE int tcase; scanf("%d",&tcase); while(tcase--) { scanf("%lf%lf%lf",&x,&y,&v); if(x==0&&y==0) { printf("0.000000\n"); continue; } if(y==0) { printf("-1\n"); continue; } if(x==0) { if(v*v*0.5/g>=y) printf("%.6lf\n",PI/2); else printf("-1\n"); continue; } double l=0,r=PI/2; int cnt=10000; while(cnt--) { double mid=(l+r)/2; double mmid=(mid+r)/2; if(geth(mid)>geth(mmid)) r=mmid; else l=mid; } if(geth(r)<y) { printf("-1\n"); continue; } l=0; r=r; cnt=10000; while(cnt--) { double mid=(l+r)/2; if(geth(mid)>y) r=mid; else l=mid; } printf("%.6lf\n",r); } return 0; }