C++代码 有一个包含 n 个数的数列,从中选出两个不同位置的数形成一个数对,要求:较左边的数除以 3 的余数 ≤ 较右边的数除以 3 的余数。(使用前缀和)
时间: 2024-12-13 09:20:39 浏览: 15
在C++中,要解决这个问题,我们可以使用前缀和(Prefix Sum)的概念,也称为累积和,来处理这种余数限制的范围查找问题。这里我们假设数组 `nums` 存储了长度为 `n` 的整数,并且需要找到满足条件的所有数对 `(i, j)`,其中 `0 <= i < j < n`,并且 `nums[i] / 3` 的余数不大于 `nums[j] / 3` 的余数。
首先,我们需要计算每个元素及其除以3后的余数,然后将这些余数存入另一个数组 `prefix_sum` 中。对于每个元素,我们将它的值加上前面所有元素除以3后余数的最小值,这样可以保证新数组 `prefix_sum` 中的每个元素都是对应位置原数组元素所能得到的最大有效余数。
接下来,遍历 `prefix_sum`,对于每个元素 `prefix_sum[i]`,寻找所有大于它的元素 `prefix_sum[j]`(`j > i`),这样就可以保证 `nums[i]` 对应的余数小于等于 `nums[j]` 对应的余数。同时,由于我们已经处理过最大有效余数,所以不需要检查 `j - i` 是否大于1。
下面是一个简单的C++代码示例:
```cpp
#include <vector>
using namespace std;
vector<int> prefixSum(const vector<int>& nums) {
int n = nums.size();
vector<int> prefix(n + 1, 0);
for (int i = 1; i <= n; ++i) {
prefix[i] = (prefix[i - 1] + nums[i - 1]) % 3;
}
return prefix;
}
void findPairs(vector<int>& nums, vector<int>& prefix) {
int n = prefix.size();
bool found = false;
for (int i = 0; i < n - 1; ++i) {
for (int j = i + 1; j < n; ++j) {
if (prefix[j] >= prefix[i]) {
cout << "(" << i << ", " << j << ") : " << "nums[" << i << "]/3 mod 3 <= nums[" << j << "]/3" << endl;
found = true;
}
}
}
if (!found) {
cout << "No valid pairs found." << endl;
}
}
int main() {
vector<int> nums = {1, 2, 4, 6, 9}; // 示例数组
vector<int> prefix = prefixSum(nums); // 计算前缀和
findPairs(nums, prefix);
return 0;
}
```
运行这个程序,它会输出满足条件的数对。如果不存在这样的数对,则会输出提示信息“无有效对”。
阅读全文