🏀 弹球模拟 - 算法可视化教学

📋 题目描述

一个球在一条有 n 个格子的直线上运动,格子编号从 1 到 n。球初始位于位置 p,初始方向向右。

每次移动,球会向当前方向前进 1 格。如果球会越过边界(小于 1 或大于 n),则会在边界处反弹:
• 当球要越过右边界时,会反弹向左
• 当球要越过左边界时,会反弹向右

给定初始位置 p 和移动步数 v,求移动 v 步后球的位置。

📥 输入格式

一行三个整数 n、p、v(1 ≤ n ≤ 100,1 ≤ p ≤ n,1 ≤ v ≤ 100)

📤 输出格式

一个整数,表示移动 v 步后球的位置

💡 核心思想

使用循环模拟每一步:
1. 用变量 pos 记录当前位置
2. 用变量 dir 记录方向(1=向右,-1=向左)
3. 每次移动后检查边界,到达边界时反转方向
4. 模拟 v 步后输出最终位置

📊 样例输入

10 2 3 5 3 8

📊 样例输出

5 3

📌 注意事项

• 方向变量初始值为 1(向右)
• 到达右边界(pos == n)时方向改为 -1
• 到达左边界(pos == 1)时方向改为 1
• 循环执行 v 次,不是 v-1 次
步骤
0
当前位置
-
当前方向
-
剩余步数
-
点击「自动播放」或「单步」开始演示

💡 当前步骤

点击「自动播放」或「单步」开始演示

📈 执行记录

步骤 位置 方向

⏱ 时间复杂度

O(v)
需要模拟 v 步移动

💾 空间复杂度

O(1)
只需要几个变量

⚠️ 常见错误

• 忘记初始化方向变量 dir = 1
• 在移动之前就检查边界
• 循环次数写成 v-1 而不是 v
• 方向搞反(把 -1 当成向右)

💻 C++ 参考代码

// 弹球模拟 #include <iostream> using namespace std; int main() { int n, p, v; cin >> n >> p >> v; int pos = p; // 当前位置 int dir = 1; // 方向:1表示向右,-1表示向左 for (int i = 0; i < v; i++) { pos += dir; // 向当前方向移动一格 if (pos == n) { dir = -1; // 到达右边界,反弹向左 } else if (pos == 1) { dir = 1; // 到达左边界,反弹向右 } } cout << pos << endl; return 0; }