Problem:acm.hdu.edu.cn/showproblem.php?pid=5826
题意:n 个球在光滑轨道上直线运动,任意事刻都满足:a * v = c,a 是加速度,v 是速度,c 是给定常数,且碰撞时弹性碰撞
q 个询问,问开始后的 t 时刻,所有球的速度中第 k 小的速度大小
分析:弹性碰撞,速度交换,a * v = c,所以 a 也跟着 v “交换”,所以直接看成是穿过对方继续向前运动,初始位置、方向都没用
由 a * v = c 可以看出 a 和 v 一直在变,把 a 写成 dv / dt 的形式,dt 乘过去,两边积分,得: v ^2 = v0 ^2 + 2 * c * t (v0 是给定的初速度)
两边积分变量不同,注意积分上下限,dv 是 v0 到 v,dt 是 0 到 t(大概是把 v 看成 t 的函数之类的)
从式子看出,t 单位时间后的各球的速度大小排序 和 各球的 v0 的大小排序应该是一样的
(传参数给 sqrt() 的时候还是传个 double 型的好,整型不乘 1.0 实测 wa 了一发…)
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define N 100000
int v[N];
int cmp(const void *a, const void *b)
{
return *(int*)a - *(int*)b;
}
int main()
{
int iTom;
scanf("%d", &iTom);
while( iTom-- )
{
int n,c,i,q;
scanf("%d%d", &n, &c);
for(i=0; i<n; i++)
scanf("%d%*d%*d", v+i);
// 先对初速度排序
qsort(v, n, sizeof(int), cmp);
scanf("%d", &q);
while( q-- )
{
int t,k;
scanf("%d%d", &t, &k);
// 直接拿第k小的速度来算
printf("%.3f\n", sqrt(1.0 * v[k-1] * v[k-1] + 2.0 * c * t) );
}
}
return 0;
}

810

被折叠的 条评论
为什么被折叠?



