HDU2298(三分+二分求解方程,入门,模板)

题意:

小球发射速度为v,求在(0,0)击中(x,y)处的目标,求发射角度。

 

题解:

设f(a)表示:角度为a,小球的横坐标与目标相同时,小球的高度。

计算可得f(a) = x*tan(a) -  (4.9 * x ^2 / v^2) *  (tan(a)^2 + 1)

这明显就是一个单峰函数,可用三分法求解峰值。

求解出峰值后,再用二分搜索,求解高度为y的角a.

关于三分搜索可以详见:https://blog.csdn.net/pi9nc/article/details/9666627

 

#include<bits/stdc++.h>
using namespace std;
double eps=1e-10;
double x,y,v;
double cal(double a)
{
	double t = x/(v*cos(a));
    return v*sin(a)*t - 9.8/2*t*t;
}
int main()
{
	//freopen("t.txt","r",stdin);
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%lf%lf%lf",&x,&y,&v);
		double a = acos(-1.0)/2;
        if(x==0) //特判,否则三角函数会智障掉
        {
            if(v*v/2/9.8 > y) printf("%.6lf\n", a);
            else printf("-1\n");
            continue;
        }
        double l=0,r=a,mid_l,mid_r,mid;
        while(r-l>eps)
        {
        	mid_l=l*2/3+r/3;
        	mid_r=r*2/3+l/3;
        	if(cal(mid_l)>cal(mid_r))
        	{
        		r=mid_r;
			}else
			{
				l=mid_l;
			}
		}
		//cout<<eps<<"*"<<endl;
        if(cal(l)<y)
		{
			printf("-1\n");
			continue;
		} 
		r=l;l=0;
		while(r-l>eps)
		{
			mid=(r+l)/2;
			if(cal(mid)<y)
			{
				l=mid;
			}else
			{
				r=mid;
			}
		}
		printf("%.6lf\n", l);
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值