POJ 3684 Physics Experiment
Description
有n个小球从一管道开始下落,每秒钟下落一个,已知管口离地面的距离h及小球半径r,所有的碰撞均是弹性碰撞,求ts时,各个小球的位置
http://poj.org/problem?id=3684
Idea
他们的碰撞可以视为没有碰撞,只是穿过了对方,而这种思路适用于没有半径的时候,其实有半径的时候也可以这样来解决
- 假所有的小球都是没有半径的,且从同一高度每隔1s掉下,,很显然,这个时候求t时的小球的位置,只要求出单独的小球位置,然后再sort排个序就好,(sort排序是因为小球相对位置不变,即刚释放时最下边的小球不管怎么跳还是在最下面),这个时候跟蚂蚁是几乎差不多的,碰了等于没碰。
- 假设两个小球是有半径的,且是紧挨着每隔1s落下,这时候,因为小球有半径,其实碰了还是等于没碰
- 对于从下方数第i个球,在按照R=0计算的结果上加上2Ri就好了
Code
#include <cmath>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const double g = 10.0;
int N, H, R, T;
double y[105];
double cal(int t)
{
if(t < 0)
return H;
double TT = sqrt(2 * H / g); ///周期
int k = (int)(t / TT); ///最多包含多少个周期
double time;
if(k & 1) ///rise
time = k * TT + TT - t;
else ///fall
time = t - k * TT;
return H - g * time * time / 2;
}
int main()
{
int n;
cin >> n;
while(n--)
{
cin >> N >> H >> R >> T;
for(int i = 0; i < N; ++i)
y[i] = cal(T - i); ///T-i 对应释放时间
sort(y, y + N);
for(int i = 0; i < N; ++i)
printf("%.2f%c", y[i] + 2 * R * i / 100.0, i < N - 1 ? ' ' : '\n');
}
return 0;
}