思路分析
因为最终要使得 \(a,b\) 相同,所以我们应该希望让相同的数字尽量相同。所以,我们需要先对 \(a\) 和 \(b\) 进行排序,这样子就可以使用双指针的方法来维护最终值了。
我们定义 \(l\) 指针指向 \(a_l\),\(r\) 指针指向 \(b_r\)。因为题目要求添加数字的次数最少,所以我们希望尽可能地来缩小数字以减少添加数字的次数。所以如果 \(a_l<b_r\),那么我们可以将 \(l\) 增加\(1\),代表我们对于这个数可以采用减少的方法。对于每次操作,我们都需要将 \(r\) 增加 \(1\),是因为我们不能重复地操作 \(b_r\)。
复杂度分析
时间复杂度
整个程序的性能瓶颈在于对所有点进行排序,时间复杂度是 \(\mathcal O(n\log n)\) 的,对于 \(1\le n,m\le3000\) 的范围是丝毫没有问题的。
空间复杂度
我们需要两个数组 \(a\) 和 \(b\) 来存储值,\(a\) 的大小为 \(n\),\(b\) 的大小为 \(m\),所以最终的空间复杂度是 \(\mathcal O(n+m)\),也是没有问题的。
代码实现
#include <bits/stdc++.h>
using namespace std;
int n, m, l, r;
int main() {
cin >> n >> m;
vector<int> a(n), b(m);
for (auto &x : a) cin >> x;
for (auto &x : b) cin >> x;
sort(a.begin(), a.end()); // 对a数组排序
sort(b.begin(), b.end()); // 对b数组排序
while (l < n && r < m) {
if (a[l] <= b[r]) l++; // 如果a[l]<=b[r],那么我们只需将b[r]减少,不用添加数字
r++; // 继续比较下一位
}
cout << n - l; // 共有n个数字,去掉减小数字的次数,就是添加数字的次数了
return 0;
}
标签:数字,题解,复杂度,cin,数组,CF387B,排序,指针
From: https://www.cnblogs.com/IShallReturn/p/CF387B-ti-jie.html