1 条题解
-
0
📝 题目大意
给定一个长度为 的数列 和四个位置 (满足 且两段长度相等 ),将 与 这两个子段交换位置,输出交换后的数列 。
💡 解题思路
-
题目分析:
- ,数据范围极小,可以直接用 模拟交换。
- 关键约束 保证两段长度相等,因此交换时一一对应,无需额外处理不等长情况。
- 下标从 开始(题目中 为第一个元素),代码中数组也使用 1-indexed。
-
算法推导:
- 读入 以及数组 。
- 创建新数组 ,遍历 到 :
- 若 :当前位置属于第一段,应从第二段对应位置取值,即 ,其中 从 开始递增。
- 若 :当前位置属于第二段,应从第一段对应位置取值,即 ,其中 从 开始递增。
- 否则:(不在交换范围内的元素保持不变)。
- 标准代码中使用变量
s和o分别记录两段交换时的偏移量,每次取值后自增 。
-
边界与细节:
- 两段不重叠且不相邻时,中间的元素保持不变(如样例 1 中 不变)。
- 两段相邻时(),交换效果等同于整体平移,但逻辑依然正确。
- 长度为 的两段交换(即 )等价于交换两个元素,代码同样适用。
- 数组元素值可能重复,无需特殊处理。
⏱️ 复杂度分析
- 时间复杂度:,只需一次遍历。
- 空间复杂度:,需要一个辅助数组 存放结果。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; int main(){ // n=N, m=P, x=Q, y=R, z=S // s: 第一段→第二段交换时的偏移量 // o: 第二段→第一段交换时的偏移量 int n, m, x, y, z, a[105], b[105], s = 0, o = 0; cin >> n >> m >> x >> y >> z; for (int i = 1; i <= n; i++) cin >> a[i]; for (int i = 1; i <= n; i++) { if (i <= x && i >= m) { // 当前位置 i 属于第一段 [P, Q] b[i] = a[y + s]; // 从第二段 [R, S] 取对应位置的值 s++; } else if (i >= y && i <= z) { // 当前位置 i 属于第二段 [R, S] b[i] = a[m + o]; // 从第一段 [P, Q] 取对应位置的值 o++; } else { // 当前位置不在交换范围内 b[i] = a[i]; // 保持原值 } cout << b[i] << ' '; // 输出结果 } return 0; } -
- 1
信息
- ID
- 672
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者