1 条题解
-
0
📝 题目大意
给定两个严格递增且元素互不相同的序列 (长度 )和 (长度 ),将它们合并后排序得到序列 (长度 )。要求输出 中每个元素在 中的位置(1-indexed),以及 中每个元素在 中的位置。
💡 解题思路
-
题目分析:,。 和 各自严格递增且两两不同,因此 就是 和 归并后的序列。本质上是求两个有序序列的归并过程中每个元素的排名。
-
算法推导:使用双指针归并,模拟归并排序的过程。
- 定义指针
i(遍历 ,从 开始)、j(遍历 ,从 开始)、k(当前归并到的位置,从 开始)。 - 数组
c[i]记录 在 中的位置,数组d[j]记录 在 中的位置。 - 当
i <= n且j <= m时,比较a[i]和b[j]:- 若
a[i] < b[j],则c[i] = k,i++,k++。 - 否则,
d[j] = k,j++,k++。
- 若
- 循环结束后,将剩余元素(全部来自 或全部来自 )依次赋予位置
k。 - 最终按顺序输出
c[1..n]和d[1..m]。
- 定义指针
-
边界与细节:
- 由于 和 各自严格递增,双指针归并不会有重复值问题。
- 当某一序列先耗尽时,需要将另一序列的剩余部分一次性处理完。
- 输出两行,每行末尾有空格不影响评测(AtCoder 一般允许行末空格)。
⏱️ 复杂度分析
- 时间复杂度:,每个元素仅被访问一次。
- 空间复杂度:,存储 、 以及位置数组 、。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; #define int long long const int N = 1e6 + 10; int n, m, a[N], b[N], c[N], d[N]; signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m; for (int i = 1; i <= n; i++) cin >> a[i]; // 读入序列 A for (int i = 1; i <= m; i++) cin >> b[i]; // 读入序列 B int i = 1, j = 1, k = 1; // i 遍历 A, j 遍历 B, k 为当前归并位置 while (i <= n && j <= m) { if (a[i] < b[j]) // A 当前元素更小,先归入 C { c[i] = k; // 记录 A[i] 在 C 中的位置 i++, k++; } else // B 当前元素更小,先归入 C { d[j] = k; // 记录 B[j] 在 C 中的位置 j++, k++; } } while (i <= n) // A 剩余部分依次归入 { c[i] = k; i++, k++; } while (j <= m) // B 剩余部分依次归入 { d[j] = k; j++, k++; } for (int i = 1; i <= n; i++) cout << c[i] << ' '; // 输出 A 各元素的位置 cout << endl; for (int i = 1; i <= m; i++) cout << d[i] << ' '; // 输出 B 各元素的位置 cout << endl; return 0; } -
- 1
信息
- ID
- 697
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者