HDU-5826 physics(物理定理+微分方程)

来源:互联网 发布:无忧保姆 知乎 编辑:程序博客网 时间:2024/06/06 17:20

题意:

给定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;}


继续加油~