题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5826
题意:有n个小球在一条直线上滚动,起始位置为xi, 方向为di(-1往左走,1往右走),初始速度为 vi; 这n个球的加速度ai和vi的关系是 ai * vi = C, C是已知常数;
n个球可能会发生碰撞,碰撞为完全弹性碰撞。然后给你q个询问,每次问你t秒后第 k 小 的速度是多少;
碰撞为完全弹性碰撞,即速度交换,但是大小不变,所以我们可以忽略碰撞,也可以忽略小球的位置以及运动方向;
让求t秒后的第k小的速度,其实就是求初始时第k小的速度t秒后变为多少;因为v是越来越大的(题中说了a和v同向的),所以a是越来越小的,
当一个球A的起始速度<另一个球B时,那么A的速度最大也就是和球B的速度相等,永远不会超过球B的速度;
所以我们现在要考虑的就是已知初速度 v0 求 t 秒后的速度 v 其中加速度 a 和速度 v 的关系是 av=C;
a = dv/dt = C/v
-----> vdv = Cdt
两边同时积分v是从v0-V,t是从0到t
-----> [v*v/2](v0---v) = Ct(0----t)
-----> v = sqrt(2*C*t+v0*v0);
#include<iostream> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; #define INF 0xfffffff #define N 100050 typedef long long LL; int v[N]; int main() { int T; scanf("%d", &T); while(T--) { int n, C, x, d; 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); int q, t, k; scanf("%d", &q); for(int i=1; i<=q; i++) { scanf("%d %d", &t, &k); double ans = sqrt(2.0*C*t + 1.0*v[k]*v[k]); printf("%.3f\n", ans); } } return 0; }
时间: 2024-10-20 10:38:25