【题目大意】:有一个人站在(0,0)这个点,现在要以初速度为v的飞镖去攻击位于(x,y)的苹果,问飞镖离手是与x轴的夹角。
【解题思路】:高中物理题...直接分解初速度,然后消去t...利用sin^2+cos^2=1进行化简,变形,另tana=x...暴力解一元二次方程...几行而已
第二种做法是以苹果所在的x坐标做直线,三分得到区间(p,q)此时满足当角度在p和q之间的时候可以击中苹果。
再二分区间得到最优值。
【代码】:
//数学做法 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <string> #include <cctype> #include <map> #include <iomanip> using namespace std; #define eps 1e-8 #define pi acos(-1.0) #define pb push_back #define lc(x) (x << 1) #define rc(x) (x << 1 | 1) #define lowbit(x) (x & (-x)) #define ll long long #define g 9.8 double x,y,v,a,b,c,tmp,ans1,ans2,tanans1,tanans2; int main() { int T; scanf("%d",&T); while (T--){ scanf("%lf%lf%lf",&x,&y,&v); a=g*x*x; b=-2*v*v*x; c=2*v*v*y+g*x*x; tmp=b*b-4*a*c; if (tmp<0) { printf("-1\n"); continue; } else{ tanans1=(-b+sqrt(b*b-4*a*c))/(2*a); tanans2=(-b-sqrt(b*b-4*a*c))/(2*a); ans1=atan(tanans1); ans2=atan(tanans2); bool flag1=true,flag2=true; if (ans1<0 || ans1>=pi/2) flag1=false; if (ans2<0 || ans2>=pi/2) flag2=false; if (flag1==flag2 && flag1==false) {printf("-1\n");} else if (flag1==flag2 && flag1==true) { if (ans1>=ans2) printf("%.6f\n",ans2); else printf("%.6f\n",ans1); } else if (flag1=true) printf("%.6f\n",ans1); else printf("%.6f\n",ans2); } } return 0; }
//二分+三分 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> #include <cmath> #include <string> #include <cctype> #include <map> #include <iomanip> using namespace std; #define eps 1e-8 #define pi acos(-1.0) #define pb push_back #define lc(x) (x << 1) #define rc(x) (x << 1 | 1) #define lowbit(x) (x & (-x)) #define ll long long #define g 9.8 double low,high,mid,mmid,x,y,v; double tmp1,tmp2; double check1(double a){ // double t=x/(v*cos(a)); double ans=tan(a)*x-0.5*g*x*x/v/v/cos(a)/cos(a); return ans; } void get_extent(){ low=0,high=pi/2; while (low+eps<high) { mid=(low+high)/2.0; mmid=(mid+high)/2.0; tmp1=check1(mid); tmp2=check1(mmid); if (tmp1<tmp2) { low=mid; } else { high=mmid; } } return ; } void get_angle(){ low=0; while (low+eps<high){ mid=(low+high)/2.0; tmp1=check1(mid); if (tmp1>y) high=mid; else low=mid; } printf("%.6f\n",mid); return ; } int main() { int T; scanf("%d",&T); while (T--){ scanf("%lf%lf%lf",&x,&y,&v); get_extent(); if (max(tmp1,tmp2)<y) {printf("-1\n"); continue;} else get_angle(); } return 0; }