本文专注于记录我如何使用AI完成算法刷题练习,以此来分享如何高效利用AI刷题。
#85数列差异化最小
问题描述
给定长度分别为 n 和 m 的两个数列a[n]、b[m],和一个整数k。求|(a[i] - b[j])^2 - k^2|的最小值。
输入格式
第一行有 2 个整数 n、m、k,分别表示数列 a、b 的长度,以及公式中的整数 k。
第二行有 n 个整数,表示数列 a 的各个元素。
第三行有 m 个整数,表示数列 b 的各个元素。
输出格式
求上述公式的最小值。
数据范围
其中 20%的数据:1 <= n,m <= 3000,-10^9 <= a[i], b[j], k <= 10^9,for all i, j
其中 30%的数据:1 <= n,m <= 50000,k = 0,-10^9 <= a[i], b[j] <= 10^9,for all i, j
其中 50%的数据:1 <= n,m <= 50000,-10^9 <= a[i], b[j], k <= 10^9,for all i, j
输入样例
5 5 1
5 3 4 1 2
0 6 7 9 8
5 5 0
5 3 4 1 2
0 6 7 9 8
输出样例
0
1
思路
这个问题是个数学问题,关键在于我们的算法能不能解决规模量较大的5万内的情况。给定两个数列 a 和 b,以及一个整数 k,我们需要计算每对 a[i] 和 b[j] 之间的差值 (a[i] - b[j]) 的平方,并与 k^2 进行比较,求出最小的值,最终返回 |(a[i] - b[j])^2 - k^2| 的最小值。
-
公式解析:
- 目标公式是
|(a[i] - b[j])^2 - k^2|,这可以看作是(a[i] - b[j])^2和k^2之间的差值的绝对值。 - 我们需要计算所有可能的
(a[i] - b[j])^2,然后找到与k^2最接近的差值。
- 目标公式是
-
直接暴力解法:
- 遍历每一对
a[i]和b[j],计算(a[i] - b[j])^2,然后求与k^2的差值。 - 时间复杂度是
O(n * m),对于最大数据范围可能会超时。
- 遍历每一对
-
优化思路:
- 将所有可能的
(a[i] - b[j])^2存储在一个列表中,并排序。 - 然后,我们可以使用 二分查找 来快速找到与
k^2最接近的平方差,避免暴力搜索。
- 将所有可能的
代码实现
#include <climits>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
int solution(int n, int m, int k, vector<int>& a, vector<int>& b) {
// 计算 k 的平方
int k_square = k * k;
// 用来存储所有 (a[i] - b[j])^2 的结果
vector<int> diff_squares;
// 计算并存储所有 (a[i] - b[j])^2 的值
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
diff_squares.push_back((a[i] - b[j]) * (a[i] - b[j]));
}
}
// 排序差值的平方数组
sort(diff_squares.begin(), diff_squares.end());
// 最小差值初始化为一个较大的数
int min_diff = INT_MAX;
// 对每个 (a[i] - b[j])^2 计算与 k^2 的差值
for (int diff : diff_squares) {
min_diff = min(min_diff, abs(diff - k_square));
}
return min_diff;
}
int main() {
// 测试用例
vector<int> a1 = {5, 3, 4, 1, 2};
vector<int> b1 = {0, 6, 7, 9, 8};
cout << (solution(5, 5, 1, a1, b1) == 0) << endl;
vector<int> a2 = {5, 3, 4, 1, 2};
vector<int> b2 = {0, 6, 7, 9, 8};
cout << (solution(5, 5, 0, a2, b2) == 1) << endl;
vector<int> a3 = {5, 3, 4, 1, 2};
vector<int> b3 = {0, 6, 7, 9, 8, 11};
cout << (solution(5, 6, 3, a3, b3) == 0) << endl;
return 0;
}
-
计算差值的平方:
- 对于每对
a[i]和b[j],计算diff = (a[i] - b[j])^2。 - 将所有的
diff保存到一个列表中。
- 对于每对
-
二分查找优化:
- 将所有计算出来的平方差
diff排序。 - 使用二分查找(
lower_bound)来找到最接近k^2的差值。
- 将所有计算出来的平方差
-
时间复杂度:
- 计算所有的平方差时间复杂度是
O(n * m)。 - 排序时间复杂度是
O(n * m * log(n * m))。 - 使用二分查找的时间复杂度是
O(log(n * m))。
- 计算所有的平方差时间复杂度是