题意:
n≤10个障碍物,一个球从起点弹到终点距离为d≤10000,反弹次数b≤15,重力g=1
不计中间过程的能量损失,问可以越过所有障碍物最小的初速度是多少?
分析:
由于反弹次数很小,我们可以考虑枚举反弹次数,由于障碍物个数也很少我们也可以枚举障碍物假设所求的速度为v,vx=vcosθ,vy=vsinθ,根据水平时间与竖直时间相等可知,12lvx=vyg
可得l=2vxvyg=v2⋅2sinθcosθg=v2⋅sin2θg ①
对于相同的速度的情况下,θ=45度时,l取到最大值为最优,所以出射角应该≥45度
对于每个反弹次数,我们可以得到球运动的抛物线的宽度l=d/(i+1)
对于一个包含障碍物的抛物线周期,我们知道三个点(0,0),(x,hi),(l,0),其中x是所在抛物线周期的pi位置
根据抛物线两根式y=a(x−x1)(x−x2)=>y=ax(x−l),解得:a=hi/(x∗(x−l))
求导y=ax(x−l)得到抛物线的斜率方程y′=2ax−al,代入x=0得,tanθ=−al,即θ=atan(−al) ②
由①变形得,v2=lgsin2θ,再由②即可算出v2
问题解决,不要忘记特判碰到障碍物的情况
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<string>
#define OPENSTACK
using namespace std;
typedef long long ll;
typedef pair<ll,ll>P;
const int INF=0x3f3f3f3f;
const ll INFF=0x3f3f3f3f3f3f3f3f;
const double pi=acos(-1.0);
const double eps=1e-9;
int d,n,b;
int p[20],h[20];
double solve(int i)
{
double l=d*1.0/(i+1);
double ans=0;
for(i=1;i<=n;i++)
{
double yu=fmod(p[i],l);
if(fabs(yu)<eps)
return 1e20;
double a=h[i]*1.0/yu/(yu-l);
double angle=-a*l;
angle=max(pi/4,atan2(angle,1.0));
ans=max(ans,l/sin(2*angle));
}
return ans;
}
int main()
{
while(scanf("%d%d%d",&d,&n,&b)!=EOF)
{
for(int i=1;i<=n;i++)
scanf("%d%d",&p[i],&h[i]);
double ans=1e20;
for(int i=0;i<=b;i++)
{
ans=min(ans,solve(i));
}
printf("%.8lf\n",sqrt(ans));
}
return 0;
}
126

被折叠的 条评论
为什么被折叠?



