C++代码 有一个包含 n 个数的数列,从中选出两个不同位置的数形成一个数对,要求:较左边的数除以 3 的余数 ≤ 较右边的数除以 3 的余数。(使用前缀和并且时间复杂度为 O( n ) )
时间: 2024-12-13 15:20:20 浏览: 5
统计字符串中字母和数字个数
在C++中,你可以使用前缀和(Prefix Sum)的概念来解决这个问题。前缀和是一个数组,其中每个元素表示到该索引为止所有元素的和。对于给定的数列`arr[]`,你可以创建一个新的数组`prefixSum[]`,其中`prefixSum[i] = arr[0] + arr[1] + ... + arr[i]`。然后,对于每个索引`i`,找到满足条件的最小索引`j > i`,使得`arr[j] - arr[i]`能被3整除。这个操作可以在线性时间内完成。
以下是实现这种算法的一个简单示例:
```cpp
#include <vector>
using namespace std;
// 函数返回在索引 j(j > i)处满足条件的最小值
int findValidIndex(int prefixSum[], int n, int i, int target) {
int low = i + 1, high = n;
while (low <= high) {
int mid = (low + high) / 2;
if (prefixSum[mid] - prefixSum[i] >= target) {
high = mid - 1;
} else {
low = mid + 1;
}
}
return low;
}
// 主函数
void solve(const vector<int>& arr, int n) {
vector<int> prefixSum(n + 1);
for (int i = 0; i < n; i++) {
prefixSum[i+1] = prefixSum[i] + arr[i];
}
for (int i = 0; i < n; i++) {
// 目标是 arr[i] * 3 + 1 和 arr[i] * 3 + 2
int validIndex1 = findValidIndex(prefixSum, n, i, arr[i] * 3 + 1);
int validIndex2 = findValidIndex(prefixSum, n, i, arr[i] * 3 + 2);
// 检查有效索引是否大于 i,并保存结果
if (validIndex1 > i && validIndex2 > i) {
cout << "Pair found: (" << arr[i] << ", " << arr[validIndex1] << ") and (" << arr[i] << ", " << arr[validIndex2] << ")" << endl;
}
}
}
int main() {
vector<int> arr = {4, 6, 9, 15, 21}; // 示例数列
int n = arr.size();
solve(arr, n);
return 0;
}
```
阅读全文