Physics Experiment POJ 3684(弹性碰撞)
原题
题目分析
先考虑只有一个球的时候,由运动学定理可知有,设t=sqrt(2H/T),kt<=T,当k为偶数时,h=H-(1/2)*g*(T-kt)2,当k为奇数时,h=H-(1/2)*g*((k+1)t-T)2.再考虑当R=0的时候,这时候所有球的投放起点高度都为H,在空中发生碰撞的时候,两球直接交换交换速度,由于R=0,此时可视作忽略碰撞,每个球都做独立自由落体运动.则最后球的位置可由以上公式求出,由于存在碰撞,实际上球的位置是固定的,也就说先放的球一定在最下面,因此只需对求出来的球的位置排升序即可依次确定第零个球到最后一个球的位置.最后考虑半径不为零的时候,此时分别分析球的运动情况可知道,球i(从0开始计数)只在高度为[2*R*i,H+2*R*i]里面运动,区间长度仍为H,整体运动情况仍可视为各个球的运动情况的叠加,因此可按R=0的情况处理,第i个球只需要在按R=0计算的基础上加上2*R*i即可.最后注意一下T是有可能小于N的,这时候球被固定还没开始运动.
代码
1 #include <cstdio> 2 #include <cstdlib> 3 #include <iostream> 4 #include <algorithm> 5 #include <utility> 6 #include <ctime> 7 #include <cmath> 8 #include <cstring> 9 #include <string> 10 #include <stack> 11 #include <queue> 12 #include <vector> 13 #include <set> 14 #include <map> 15 16 using namespace std; 17 typedef unsigned long long ULL; 18 typedef long long LL; 19 typedef long double LB; 20 const int INF_INT=0x3f3f3f3f; 21 const LL INF_LL=0x3f3f3f3f3f3f3f3f; 22 23 const double G=10.0; 24 25 double num[100]; 26 27 int main() 28 { 29 // freopen("testdata.in","r",stdin); 30 // freopen("std.out","w",stdout); 31 int C; 32 cin>>C; 33 while(C--) 34 { 35 int N,H,R,T; 36 cin>>N>>H>>R>>T; 37 double t=sqrt(2*H/G); 38 for(int i=0;i<N;i++) 39 { 40 int t0=T-i; 41 if(t0<=0) num[i]=H; 42 else 43 { 44 int k=(int)(t0/t); 45 if(k&1) 46 num[i]=H-G*(k*t+t-t0)*(k*t+t-t0)/2; 47 else 48 num[i]=H-G*(t0-k*t)*(t0-k*t)/2; 49 } 50 } 51 sort(num,num+N); 52 for(int i=0;i<N;i++) 53 printf("%.2f%c",num[i]+2*i*R/100.0,i==N-1?'\n':' '); 54 } 55 56 return 0; 57 }