[CSP-S模拟测试]:物理课(数学)
题目传送门(内部题144)
输入格式
从$physics.in$读入数据。
第一行一个数$T$,代表有$T$组数据。接下来$T$行每行$4$个浮点数,分别为$\theta,v,d,g$,保留到小数点后两位。
输出格式
输出答案到$physics.out$。
共$T$行,每行一个浮点数表示猫离起点的距离,四舍五入到$5$位小数。
样例
样例输入:
3
45 10 0.5 10
3.44 2.35 0.77 1.76
2.33 2.33 0.78 9.8
样例输出:
13.33333
0.92330
0.11493
数据范围与提示
样例解释:
对于第一个样例,如图所示,最终猫会停留在$(\frac{40}{3},0)$,距离原点距离约为$13.33333$。
物理大佬请无视下面这句话......
提示:对于垂直速度为$v$的物体将在飞行$\frac{v}{g}$的时间后到达最高点,速度分解使用平行四边形定则。
数据范围:
$subtask1:50pts,d=0$。
$subtask2:50pts,0\leqslant v\leqslant 1,000,0<g\leqslant 1,000,0\leqslant d<1,0<\theta<90,T\leqslant 50,000$。
(良心出题人没有构造坑人数据,不会卡精度的,只要你相信我)
$P.S.$这道题可能违背一些物理常识,但是有($chu$)一($ti$)些($ren$)原($tai$)因($cai$),就凑合着当水题做吧。
题解
刚看到这道题的时候已经停课集训$60$多天的我还真的认真回忆了一下公式……
还好想起来了……
首先,要把速度分解,这个不难,水平方向上就是$\cos\theta v$,竖直方向上就是$\sin\theta v$。
但是发现输入中给的角度是角度制,如果直接调用库里的函数需要先将其转化为弧度制。
其实$360^{\circ}=2\pi$,所以$\frac{\theta\pi}{180}$就变成了弧度制。
可能有同学说忘了$\pi$(您别说还真有)。
库里还有一个叫做$M\text{_}PI$的东西(具体操作看下面代码)。
知道了竖直方向上的速度,又知道重力加速度,就能根据公式$t=\frac{v_y}{g}$求出$t$了。
接着根据$s=v_xt$就能求出水平移动的距离了。
对于反弹,因为是等比数列,所以用等比数列求和公式即可做到$\Theta(1)$;也可以$while(1)$迭代至稳定,我就是这么做的(懒),精度设置成$1e-6$即可,$0.99^{1000}=0.000043171$,所以时间上也是没问题的。
时间复杂度:$\Theta(T\times 1000)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
const double eps=1e-6;
double theta,v,d,g;
int main()
{
int T;scanf("%d",&T);
while(T--)
{
scanf("%lf%lf%lf%lf",&theta,&v,&d,&g);
theta=theta*M_PI/180;
double SIN=sin(theta);
double COS=cos(theta);
double res=v;
double ans=0.0;
while(res>eps)
{
double t=2*SIN*res/g;
ans+=COS*res*t;
res*=d;
}
printf("%.5lf\n",ans);
}
return 0;
}
rp++