这题,题目的意思是,有N个球从高度为H的地方落下,每一秒落下一个球,球与球之间和球与地板直接都是弹性碰撞,求T秒后的每个球的位置,也就是高度。
这题,跟Ants那题类似,也就是球与球碰撞可以当作不转换方向,继续按照原来的方向。也就是R = 0的时候,忽略半径,算出每一个球的位置,每一个球与地板碰撞后,会上升到原来的高度。先算出一次掉落需要t = sqrt(2 * H / g);每个球总共的时间T,总共的完整的来回有k = T / t次。
k为奇数,最终高度为H - g * (k * t + t - T)^ 2。
k为偶数,最终高度为H - g * (T - k * t)^ 2。
算出每一个球,排序后,就是各个球最终的位置,不过球的R为0.
因为R 大于等于1。所以,最后加上2 * i * R / 100.0就OK了,i是第i个球,因为R的单位是厘米,所以除以100.0。
下面的是AC的代码:
#include <iostream>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
int N, H, R, T;
const double g = 10.0;
double y[105];
double fun(int t)
{
if(t < 0)
return H;
double d;
double temp = sqrt(2 * H / g);
int k = int(t / temp);
if(k % 2 == 0)
{
d = t - temp * k;
}
else
{
d = k * temp + temp - t;
}
return H - g * d * d / 2;
}
void solve()
{
for(int i = 0; i < N; i++)
{
y[i] = fun(T - i);
}
sort(y, y + N);
for(int j = 0; j < N; j++)
{
j == N - 1 ? printf("%.2lf\n", y[j] + 2 * R * j / 100.0)
<span style="white-space:pre"> </span>: printf("%.2lf ", y[j] + 2 * R * j / 100.0);
}
}
int main()
{
int c;
scanf("%d", &c);
while(c--)
{
scanf("%d%d%d%d", &N, &H, &R, &T);
solve();
}
return 0;
}