今天做上个三分的题时无意间看见某高手的一句话,为了做某个类型题,先去水水这类型的题。
在这里表表决心,每水完一个题,再找一个这个类型的题。还有趁着这几天的假期,把以前做过的类型水水,加强熟练程度。
题意:
bob射向一个水果,给出水果的坐标,以及初始的速度。求最小的角度(与x轴)。
分析:
由题意,不难找出两个关系式,a属于0-PI/2;
垂直方向上,v*sin(a)-g*t*t/2=y;
水平方向上,v*cos(a)*t=x;
整理两个方程式,y=v*sin(a)*x/(v*cos(a))-g*(x*x/(2*v*v*cos(a)*cos(a)))
又,1/cos(a)^2=1+tan(a)^2;
g*x*x*tan(a)-2*v*v*x*tan(a)+2*v*v*y+g*x*x=0;先减小后增大的函数
到此,可以二分解决求a的最小值。先二分得到a的极值,然后,逐渐逼近x(a越大,y越大;a越小,y越大)。
还可以直接解方程把tan(a)当成未知量x,由此转化成了一元二次方程求根。
此处贴出主要代码:
求根法 first=0;
end=PI/2;
a=g*x*x;
b=-2*v*v*x;
c=2*v*v*y+g*x*x;
d=b*b-4*a*c;
t1=(-b+sqrt(d))/(2*a);
t2=(-b-sqrt(d))/(2*a);
d1=atan(t1);
d2=atan(t2);
if((d1>=MIN && d1<=end) && (d2>=first && d2<=end))
printf("%.6lf\n",d1<d2?d1:d2);
else if(d1>=first && d1<=end)
printf("%.6lf\n",d1);
else if(d2>=first && d2<=end)
printf("%.6lf\n",d2);
else
printf("-1\n");