原题题面
题目描述
给定两个数组 ,现在从 数组中取出一个元素 ,从 数组中取出一个元素 ,若 和 的差值小于等于 ,则这两个数可以凑成一对。
现在要求输出这两个数组可以挑出的最大的元素对数。
输入格式为:
首先输入 ,代表 数组的元素总数,然后下一行为 个 数组中的元素。
然后输入 ,代表 数组的元素总数,然后下一行为 个 数组中的元素。
输出格式为一个数,代表两个数组最大的匹配对数。
题目分析
这是一道简单的贪心题。
首先我们先将两个数组从小到大进行排序,然后用两个指针分别指向两个数组的第一个元素。
然后我们比较当前两个指针所指向的元素的大小,选择较小的指针指向的元素与另一个元素的大小进行比较,若这个元素与较大元素的差值小于等于 ,则其对最终答案的贡献加一,否则答案无变动。然后无论比较的结果如何,将较小的指针向后移动一位,并进行下一次比较。循环往复直至某个指针越界。
由于我们一开始便将数组元素排序,且每个元素对答案最多产生一的贡献,所以不存在对答案的少算和漏算现象。
最终时间复杂度为 。
Accept代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n; cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i ++) cin >> a[i];
int m; cin >> m;
vector<int> b(m);
for (int i = 0; i < m; i ++) cin >> b[i];
sort(a.begin(), a.end());
sort(b.begin(), b.end());
int ans = 0;
for (int i = 0, j = 0; i < n && j < m; )
{
if (a[i] > b[j])
{
if (a[i] - b[j] <= 1) ans ++, i ++;
j ++;
}
else
{
if (b[j] - a[i] <= 1) ans ++, j ++;
i ++;
}
}
cout << ans;
return 0;
}