1 条题解
-
0
📝 题目大意
在 4 个格子(编号 0~3)上模拟棒球跑垒过程。共 轮操作,每轮先在格子 0 放一个棋子,然后将所有棋子前移 步。移出格子 3 的棋子视为得分,求最终得分 。
💡 解题思路
-
题目分析:,,数据规模极小,直接模拟即可。关键在于每轮操作是"先放棋子,再移动棋子",且移动是同时进行的(新放的棋子也要参与当轮移动)。
-
算法推导:
- 用
count[4]记录每个格子上的棋子数量,P记录累计得分。 - 每轮 的操作:
count[0]++—— 在格子 0 放置一个棋子- 开一个
new_count[4]全零数组,遍历count[pos]:- 若
pos + A[i] >= 4:这些棋子出界, - 否则:
new_count[pos + A[i]] \gets new_count[pos + A[i]] + count[pos]
- 若
- 将
count更新为new_count,进入下一轮。
- 所有 轮结束后输出 。
- 用
-
边界与细节:
- 棋子移动是同时进行的,因此必须用
new_count暂存,不能用原地更新(否则新位置的棋子可能被重复移动)。 - 最大为 ,意味着棋子一次最多移动 4 格,从格子 0 出发可能直接出界得分。
- 当 且 全为 1 时,所有棋子都在格子 3 以内,得分 ,代码需正确处理该情况。
- 棋子移动是同时进行的,因此必须用
⏱️ 复杂度分析
- 时间复杂度:,每轮最多遍历 4 个格子。
- 空间复杂度:,两个固定大小的长度为 4 的数组。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; int main() { int N; cin >> N; vector<int> A(N); for (int i = 0; i < N; i++) { cin >> A[i]; // 读入每轮移动步数 } vector<int> count(4, 0); // count[pos]:格子pos上的棋子数量 int P = 0; // 累计得分 for (int i = 0; i < N; i++) { count[0]++; // 第1步:在格子0放置一个棋子 vector<int> new_count(4, 0);// 新数组,用于同时移动所有棋子 for (int pos = 0; pos < 4; pos++) { if (count[pos] == 0) continue; // 该格子无棋子,跳过 int new_pos = pos + A[i]; // 移动后的位置 if (new_pos >= 4) { P += count[pos]; // 超出棋盘,计入得分 } else { new_count[new_pos] += count[pos]; // 落在有效格子内 } } count = new_count; // 第2步完成,更新棋盘状态 } cout << P << endl; return 0; } -
- 1
信息
- ID
- 610
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者