• Physics Experiment 弹性碰撞 [POJ3684]


    题意

    有一个竖直的管子内有n个小球,小球的半径为r,最下面的小球距离地面h高度,让小球每隔一秒自由下落一个,小球与地面,小球与小球之间可视为弹性碰撞,让求T时间后这些小球的分布 

    Input

    The first line of the input contains one integer C (C ≤ 20) indicating the number of test cases. Each of the following lines contains four integers N, H, R, T. 
    1≤ N ≤ 100. 
    1≤ H ≤ 10000 
    1≤ R ≤ 100 
    1≤ T ≤ 10000

    Output

    For each test case, your program should output N real numbers indicating the height in meters of the lowest point of each ball separated by a single space in a single line. Each number should be rounded to 2 digit after the decimal point.

    Sample Input


    1 10 10 100 
    2 10 10 100 
    Sample Output

    4.95 
    4.95 10.20 

    Analysis

    首先这种弹性碰撞的题可以很快联想到两只蚂蚁擦肩而过的题,但是这是有半径的,是与之前视为质点的情况是不同的,如何处理?

    我们根据弹性碰撞,有动量守恒和机械能守恒,得到1,2两个求撞后的速度分别为

    V1'=2*(m1-m2)/(m1+m2)*V1+2*m2/(m1+m2)*V2

    V2'=2*(m2-m1)/(m1+m2)*V2+2*m1/(m1+m2)*V1

    那也就是1,2两个小球发生了速度交换。

    我们不妨设1为下面的求,2为上面的球,那么碰撞后(相互穿越),1的重力势能瞬间增加2mgr,速度不变,2的重力势能瞬间减少2mgr,速度也不变

    所以我们可以把他等效于就相当于没有半径的情况+某球下面的球的数量×2r

    对于计算位置,我们由H=1/2gt2可得,t=√(2H/g)

    我们令k是满足kt<=T的最大正整数,那么

    ansH=    H-1/2g(T-kt)2 (k&2==0)

        H-1/2g((k+1)t-T)2 (k&2==1)

    Code

     1 #include<cstdio>
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cstdlib>
     6 #include <cmath>
     7 #include <vector>
     8 #include <queue>
     9 #include<map>
    10 #include <algorithm>
    11 #include <set>
    12 using namespace std;
    13 #define MM(a) memset(a,0,sizeof(a))
    14 typedef long long LL;
    15 typedef unsigned long long ULL;
    16 const int mod = 1000000007;
    17 const double eps = 1e-10;
    18 const int inf = 0x3f3f3f3f;
    19 const double g=10;
    20 int cas,n,h,r,t,k;
    21 double t0,tx,a[105],temp;
    22 double solve(int x)
    23 {
    24      if(x<0) return h;
    25      t0=sqrt(2*h*1.0/g);
    26      k=int(x/t0);
    27      if(k%2==0)  temp=x-k*t0;
    28      else    temp=t0-(x-k*t0);
    29      return h-0.5*g*temp*temp;
    30 }
    31 int main()
    32 {
    33     cin>>cas;
    34     while(cas--)
    35     {
    36         scanf("%d %d %d %d",&n,&h,&r,&t);
    37         for(int i=1;i<=n;i++)
    38            a[i]=solve(t-(i-1));
    39         sort(a+1,a+n+1);
    40         for(int i=1;i<=n;i++)
    41             printf("%.2f%c",a[i]+2*(i-1)*r/100.0,i==n?'
    ':' ');//注意%s输出字符串,%c输出字符,所以这个地方不能用“”
    42     }  //因为%c无法输出“”字符串
    43     return 0;
    44 }
    View Code
  • 相关阅读:
    第六课 使用oflash软件烧写bin文件至开发板
    Linux查看、添加、修改PATH环境变量
    第七课 Linux裸机开发+SourceInsight3.5使用+notepad++使用
    第五课 Linux高级命令
    数组的方法总结
    浅谈 return false 和preventDefault stopPropagation stopImmediatePropagation 的正确用法
    实时统计输入的文字
    滚轮滚动事件
    window.onload和DOMReady
    JS获取浏览器可视区域的尺寸
  • 原文地址:https://www.cnblogs.com/ibilllee/p/9294968.html
Copyright © 2020-2023  润新知