查找数组中的最小更改数以进行 k 算术级数
Find minimum number of changes in array to make k-arithmetic progression
我最近遇到了这个问题:
在挑战中,您将获得一个由 n 个数字和一个整数 k 组成的数组。在一分钟内,您可以将数组的任何元素更改为所需的任何整数。找到您必须花费的最短时间,以便满足以下条件:对于从 i 到 1 的所有 i,n - 1,a[i] - a[i - 1] = k。由于 n, k <= 10^5,解决方案应该是线性的 (O(n(( 或者可能是 O(n * logn(,我对此表示怀疑。
我贪婪地意识到这个问题可能是DP,但我找不到答案。这个话题是相似的,但那里的答案没有用(在我看来(。我只是在寻找伪(或 cpp(代码。
UPD:我用 O(n^2( 编写了一个蛮力解决方案,如果它对您有帮助,这里是代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<double> vd;
typedef vector<bool> vb;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<pi> vp;
typedef vector<pl> vpl;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
cerr.tie(nullptr);
int n, k;
cin >> n >> k;
vi a(n);
for (auto& i : a)
cin >> i;
int res = INT32_MAX;
for (int i = 0; i < n; ++i){
int s = a[i], sol = 0;
for (int j = i + 1; j < n; ++j){
s += k;
if (a[j] != s)
++sol;
}
s = a[i];
for (int j = i - 1; j > -1; --j){
s -= k;
if (a[j] != s)
++sol;
}
res = min(sol, res);
}
cout << res << 'n';
}
我不完全确定这是否适合这里,如果我理解正确的话,您是在要求一种算法。
您需要找到最少数量的元素进行更改,以便满足进度。 我建议你减去斜率,即a[i]-=k*i
,现在您所要做的就是找到新数组中出现次数最多的数字(更重要的是,它出现的次数(。基本上,你想问某些线上有多少个点(a[i]=k*i+m(,所以你减去斜率并计算每个m
的出现次数。最常出现的m
值具有具有适当值的点数最多,因此我们所要做的就是修复所有其他点。
鉴于您的值可能很大(我假设(,您可以使用std::map
进行计数,这应该在最坏的情况下给您 O(n*log(n((。最终结果是n-maxReps
,其中maxReps
是新数组中重复次数最多的值的重复次数。正如我们所说,我们仍然需要更改的值数量,以便它们满足我们的条件。
从本质上讲,您只需计算必须修复的点数,以便它们位于您的线上。
我将把实现留给你。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '