【题意略】

【解题思路】首先考虑一下一个球的情况。此时,这只是一个单纯的物理问题。从高为H的位置下落的话需要花费的时间为T=sqrt(2*H/g)。

推出公式,在时刻T时,令k为满足kt<=T的最大整数,那么有

(1)当k是偶数时,y=H-1/2*g*(T-kt)*(T-kt);

(2)当k是奇数时,y=H-1/2g*(kt+t-T)*(kt+t-T);

然后考虑一下多个球的情况,回忆一下ants的做法就很容易设计出一个类似的正确解法了。这里我们先来考虑一下R=0的情况。如果认为所有的球都是一样的,就可以无视它们的碰撞,视为直接互相穿过继续运动。由于在有碰撞时球的顺序不会发生改变,所以忽略碰撞,将计算得到的坐标进行排序之后,就能知道每个球的最终位置。那么R>0的时候要怎么做呢?从下到上第i个球时,只需要按照第R=0计算的结果加上2Ri就行了。

【AC code】

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=200;
const double g=10.0; //重力加速度
int N,H,R,T;
double y[maxn];//球的最终位置
//求出T时刻球的位置
double cal(int T)
{
    if(T<0) return H;
    double t=sqrt(2*H/g);
    int k=(int)(T/t);
    if(k%2==0){
        double d=T-k*t;
        return H-g*d*d/2;
    }else{
        double d=k*t+t-T;
        return H-g*d*d/2;
    }
}
void solve(){
    for(int i=0; i<N; i++){
        y[i]=cal(T-i);
    }
    sort(y,y+N);
    for(int i=0; i<N; i++){
        printf("%.2f%c",y[i]+2*R*i/100.0,i+1==N?'\n':' ');
    }
}
int main()
{
    int tt;
    scanf("%d",&tt);
    while(tt--)
    {
        scanf("%d%d%d%d",&N,&H,&R,&T);
        solve();
    }
    return 0;
}