1 条题解
-
0
📝 题目大意
有 个格子排成一行, 个棋子初始放在 的位置上。进行 次操作,每次操作指定从左到右第 个棋子:若该棋子不在最右格且右侧相邻格为空,则向右移动一格;否则不动。输出最终每个棋子的位置。
💡 解题思路
-
题目分析:
- ,,数据范围很小,直接模拟即可。
- 棋子初始位置严格递增 (),且每次移动只会向右,因此棋子的相对顺序永远不会改变——第 个棋子始终是第 个棋子。
- 由于棋子不会跨越彼此,"右侧相邻格为空"等价于"第 个棋子不在第 个棋子的紧左边"。
-
算法推导:
- 用数组
pos[1..K]存储每个棋子的位置(1-indexed,与输入的第 个棋子对应)。 - 对每次操作 ,分三种情况判断:
- 已在最右格:
pos[L] == N→ 跳过。 - 右侧相邻格被占: 且
pos[L] + 1 == pos[L+1]→ 跳过(因为棋子按顺序排列,只有紧右边的棋子会阻挡)。 - 可以移动:
pos[L]++。
- 已在最右格:
- 注意当 (最后一个棋子)时,没有右边的棋子,只需检查是否在边界 。
- 用数组
-
边界与细节:
- 数组下标从 1 开始,与输入 直接对应,避免偏移转换。
- 操作过程中棋子位置始终保持递增,不需要额外维护。
- 输出时用空格分隔,末尾换行。
⏱️ 复杂度分析
- 时间复杂度:,每次操作 判断与移动。
- 空间复杂度:,仅存储棋子位置数组。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; int main() { int N, K, Q; cin >> N >> K >> Q; vector<int> pos(K + 1); // 1-indexed,pos[i] 表示从左到右第 i 个棋子的位置 for (int i = 1; i <= K; i++) { cin >> pos[i]; // 读入初始位置,已保证递增 } for (int i = 0; i < Q; i++) { int L; cin >> L; // 情况1:已在最右格,无法移动 if (pos[L] == N) { continue; } // 情况2:右侧紧邻的格子被第 L+1 个棋子占据 // 注意 L == K 时没有右边的棋子,跳过此判断 if (L < K && pos[L] + 1 == pos[L + 1]) { continue; } // 情况3:可以向右移动一格 pos[L]++; } // 输出最终结果 for (int i = 1; i <= K; i++) { cout << pos[i] << (i < K ? " " : "\n"); } return 0; } -
- 1
信息
- ID
- 606
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者