POJ 3684 - Physics Experiment (思维)

 

Physics Experiment

Time Limit: 1000MS

Memory Limit: 65536K

Description

Simon is doing a physics experiment with N identicalballs with the same radius of R centimeters. Before theexperiment, all N balls are fastened within a vertical tubeone by one and the lowest point of the lowest ball is H metersabove the ground. At beginning of the experiment, (at second 0), the first ballis released and falls down due to the gravity. After that, the balls arereleased one by one in every second until all balls have been released. When aball hits the ground, it will bounce back with the same speed as it hits theground. When two balls hit each other, they with exchange their velocities(both speed and direction).

Simon wants to know where are the N ballsafter T seconds. Can you help him?

In this problem, you can assume that thegravity is constant: g = 10 m/s2.

Input

The first line of the input contains oneinteger C (C ≤ 20) indicating the number of testcases. Each of the following lines contains four integers NHRT.
1≤ N ≤ 100.
1≤ H ≤ 10000
1≤ R ≤ 100
1≤ T ≤ 10000

Output

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

Sample Input

2

1 10 10 100

2 10 10 100

Sample Output

4.95

4.95 10.20


【题意】

用N个R厘米的球进行如下实验。

在H米高的位置设置了一个圆筒,将球垂直依次放入(每个球在开始下落时底端距离地面的高度是H+2R*i)。实验开始时有一个球开始掉落,以后每隔一秒又有一个球开始掉落。弹性碰撞,不计一切阻力。求出实验开始后T秒钟时每个球底端的高度,保留两位小数。(g=10m/s^2)

1 <= N <= 100

1 <= H <= 10000

1 <= R <= 100

1 <= T <= 10000

 

【思路】

先考虑只有一个球,那么下落时间为t = sqrt(2*H/g) 看成是一个周期。在整数时间T时刻,小球的高度

y = H – 0.5g(T-kt)^2              (k为偶数,从最高点下落至某一处)

y = H –0.5g(t-(T-kt))^2         (k为奇数,从地面弹起至某一处,由于运动的对称性,也可以看成从最高点落至该处)

利用前面贪心题目”ants”的思想,把两个球互相碰撞看成擦肩而过,然后计算每个球的最终高度最后排序输出。可以看成擦肩而过的理论依据是忽略两球本身的大小,两球在碰撞时的高度相同,重力势能相同,根据弹性碰撞两者发生速度交换,所以可看成是互相穿过对方。

(编译器要选C++才能AC,选G++直接就WA了,编译器抽风233)

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const double g = 10.0;

double t;
int N, H, R, T;
double y[150];

double calc(int T) {
	if (T <= 0) return H;//注意细节:N >= T时,有些球还来不及下落
	int k = T / t;
	if (k & 1)
		return double(H) - ((1 + k)*t - T)*((1 + k)*t - T)*g / 2.0;
	else
		return double(H) - (T - k*t)*(T - k*t)*g / 2.0;
}

int main() {
	int c;
	scanf("%d", &c);
	while (c--) {
		scanf("%d%d%d%d", &N, &H, &R, &T);
		t = sqrt(2 * H / g);
		for (int i = 0; i < N; i++) {
			y[i] = calc(T - i);
		}
		sort(y, y + N);
		for (int i = 0; i < N; i++) {
			printf("%.2lf%c", y[i] + 2 * R*i / 100.0, i + 1 == N ? '\n' : ' ');//R是厘米要换算
		}
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值