(NOIP2002提高组)洛谷P1033题:从物理到编程,详解自由落体
一、问题分析
这道题目描述了一个物理场景:天花板上有n个小球,地面有一辆小车以恒定速度移动。我们需要计算小车能接到多少个小球。关键在于理解小球下落和小车运动的时空关系。
二、物理原理
小球下落:小球从高度H自由落体,下落距离公式为d=0.5×g×t²,其中g=10m/s²
小车运动:小车以恒定速度V水平移动,位置随时间变化为S(t) = S1 + V×t
三、解题思路
计算时间范围:
小球落到小车顶部的最晚时间t_min(此时小车刚好能接到球)
小球落到地面的最长时间t_max(超过这个时间小球就落地了)
计算位置范围:
小车最早能接到球的位置s_min
小车最晚能接到球的位置s_max
检查小球位置:
遍历所有小球,检查其初始位置是否在[s_min, s_max]范围内
四、完整代码
#include <iostream> #include <cmath> #include <algorithm> using namespace std; int main() { // 输入参数:H-天花板高度,S1-小车初始位置,V-小车速度,L-小车长度,K-小车高度,n-小球数量 double H, S1, V, L, K, n; cin >> H >> S1 >> V >> L >> K >> n; int count = 0; // 记录能接到的小球数量 // 计算小车运动的时间范围 double t_min = sqrt(2 * (H - K) / 10.0); // 小车顶部刚好能接到球的最晚时间 double t_max = sqrt(2 * H / 10.0); // 小球落地的最长时间 // 计算小车在这段时间内的位置范围 double s_min = S1 - V * t_max; // 小车最早能接到球的位置 double s_max = S1 + L - V * t_min; // 小车最晚能接到球的位置 // 遍历所有小球,检查是否在小车可接范围内 for (int i = 0; i < n; ++i) { double ball_pos = i; // 第i个小球的初始位置 // 检查小球位置是否在小车可接范围内 if (ball_pos >= s_min - 0.0001 && ball_pos <= s_max + 0.0001) { count++; } } cout << count << endl; return 0; }
五、代码解析
输入处理:读取6个参数H,S1,V,L,K,n
时间计算:
t_min = sqrt(2*(H-K)/10) 小车顶部能接到球的最晚时间
t_max = sqrt(2*H/10) 小球落地的最长时间
位置范围计算:
s_min = S1 - V*t_max
s_max = S1 + L - V*t_min
小球检查:遍历所有小球,检查位置是否在范围内
原创内容 转载请注明出处