158_弹性碰撞 Physics Experiment (POJ No 3684)

 有N个半径为R厘米的球,进行如下物理实验:

 在高处为H米的地方有一个圆筒,把球都垂直放在里面,第i个球底端距离地面的高度为H+2*R*i,实验开始最下面的求先掉落,其他求保持位置不变,

 然后每秒放一个球,不计空气阻力,都是弹性碰撞,要求T秒后所有球的位置。

 这样来考虑:在第二个,第三个球下面连接n-1个“虚拟球”,速度与原球一致,而碰撞只有在最底部的虚拟球与虚拟球底边接触时才发生,效果和实际求碰撞一致。

 所以每当发生碰撞时两个底部的虚拟球交换速度,可以当做互相穿过,互不影响,只是每个一串球最底部编号要按照高度重新分配(实际情况中球的次序是永远不会改变的)。

 而实际的那个球肯定是和对应的底部虚拟球保持2R*i的高度差(如第二个球肯定和第二号虚拟球连接)所以可以获得递推式:

 每串求最底部按个虚拟球高度肯定为H,所以相当于不受任何影响的自由落体,而实体球在其基础上再增加2R*i的高度差。

 题源来自《挑战程序竞赛》第二版158页,书中的解释不太明确,有点含糊,所以这里给出了以上证明,不知道是否有更好的证明方式。


 

//
//  158_Physics experiment.cpp
//  changlle
//
//  Created by user on 1/10/16.
//  Copyright (c) 2016 user. All rights reserved.
//

#include <iostream>
#include <math.h>
using namespace std;

int N=2;
int H=10;
int R=10;
int T=100;

const double g=10.0;

double y[2];

double calc(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]=calc(T-i);
    }
    
    sort (y,y+N);
    for (int i=0;i<N;i++)
    {
        y[i]=y[i]+2*R*i/100.0;
        cout<<y[i]<<"  ";
    }
}

int main() {
    
    solve();
    return 0;
    
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值