【洛谷 P1033】自由落体

传送门

前言

震惊,我居然在信息里推物理式子!

其实这一题出题人比较良心,没有卡精度,用 ( exttt{double}) 就能过。但这题坑点还是有的。

分析

首先让我们来推式子。

对于任意一个小球,下落的时间是一样的,从公式:

(d=0.5 imes g imes t^2)

可得

(t=sqrt{dfrac{d}{0.5g}})

(ecause g=10\ herefore t=sqrt{dfrac{d}{5}})

因为球只要 ( exttt{x}) 轴和车有重合且在那一瞬间的高度 (h_0) 满足 (kge h_0ge0) 小车即可接住这个球(居然不会被车头撞飞),所以小车可以接住小球的时间 (t_0) 满足:

(sqrt{dfrac{h}{5}}ge t_0gesqrt{dfrac{h-k}{5}})

然后我们就算这个时间段内小车穿过了多少个小球的 ( exttt{x}) 轴就行了,但这似乎有些难度,我们可以把它转换成求哪个编号的球小车最早可以接住,哪个编号的球小车最晚可以接住。

首先根据上面哪个公式可以得到:

(t_{min}=sqrt{dfrac{h-k}{5}}\t_{max}=sqrt{dfrac{h}{5}})

最早接住的球的编号 (i_b)(s_1-t_{min} imes v+l) ,记住这里要加上 (l) ,因为最早的球可以被车尾接住。

最晚接住的球的编号 (i_e)(s_1-t_{max} imes v)

(ecause i_b>i_e\ herefore exttt{ans}=i_b-i_e)

所以就有代码:

#include<bits/stdc++.h>
using namespace std;
int n;
double h,s1,v,l,k;
int main()
{
    cin>>h>>s1>>v>>l>>k>>n;
    double t_max=sqrt(h/5);
    double t_min=sqrt((h-k)/5);
    int i_b=int(s1-t_min*v+l),i_e=int(s1-t_max*v);
    cout<<i_b-i_e;
}

但是到这里就结束了吗?

我们可以发现这份代码连样例都过不了,因为存在一些特殊情况,如 (i_b>n) 或者 (i_e<0),也就是我们把一些没有球的 (mathit{x}) 轴也算成有球并被小车接住了。但这个问题其实很好解决,因为我们只要把极端的情况处理到边界上就行了。因此,我们再加上:

(i_b=min(i_b,n)\i_e=max(i_e,0))

就行了。

然后就是真正的 ( exttt{AC}) 代码了:

#include<bits/stdc++.h>
using namespace std;
int n;
double h,s1,v,l,k;
int main()
{
    cin>>h>>s1>>v>>l>>k>>n;
    double t_max=sqrt(h/5);
    double t_min=sqrt((h-k)/5);
    int i_b=int(s1-t_min*v+l),i_e=int(s1-t_max*v);
    i_b=min(i_b,n);i_e=max(i_e,0);
    cout<<i_b-i_e;
}

后记

来源

原文地址:https://www.cnblogs.com/Sam2007/p/13557193.html