题意:
给定n个质量相同的小球,在光滑的水平面上移动,每个小球有一个初始速度v0,位置x0,方向d(-1或者1),给定一个常数c,小球在移动的过程中有一个加速度a,始终满足a*v=c。小球之间进行碰撞属于完全弹性碰撞,给定q次询问,每次询问一个t和k,问t秒后速度第k小的速度为多少,输出保留3位小数。
思路:
由于小球质量相等,且满足完全弹性碰撞,所以两个小球碰撞后只会交换速度(也包括方向)。现在要求t秒后速度第k小的速度,经分析会发现初始时速度第k小的速度若干秒后仍然是第k小,因为速度是一直增加的,且完全弹性碰撞又不会损失动能,因此若干秒后第k小的速度只不过是移动到其它小球上,而题目只要求速度,所以我们就可以忽略掉小球的位置和方向了。
根据题目条件可以列出式子加速度a = c/v,所以根据导数的几何意义,可以列出方程dv/dt=c/v,得到微分方程vdv = cdt,两端同时积分得1/2*v*v = ct+b(常数),然后根据t = 0时刻速度为vo求得常数b = 1/2*v0*v0,然后代入求解v即可。
突然回忆:log(a)b的导数是1/b*lna
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+5;
int tt, n, c, x, d, q, t, k;
int v[maxn];
int main()
{
for(scanf("%d", &tt); tt--;)
{
scanf("%d %d", &n, &c);
for(int i = 1; i <= n; ++i)
scanf("%d %d %d", &v[i], &x, &d);
sort(v+1, v+n+1);
scanf("%d", &q);
while(q--)
{
scanf("%d %d", &t, &k);
printf("%.3f\n", sqrt(2ll*c*t+1ll*v[k]*v[k]));
}
}
return 0;
}
继续加油~