给定一个由正数组成的数组arr [] ,任务是找到其和可被M整除的最大范围[L,R]。如果不存在范围,则返回-1。
例子:
Input: arr[] = {3, 7, 5, 2, 5, 10}, M = 3
Output: 1 3
Explanation: Sum of numbers from 1 to 3 is 3+7+5 which is 15.
Input :
A[] = {4, 8, 12, 16, 20}
M = 11
Output :
-1
幼稚的方法:幼稚的方法是我们可以遍历数组中所有可能的L和R并检查和是否可整。如果是,则存储数组的长度。
高效的方法:这里的想法是使用前缀和数组。
- 最初,将计算值的前缀和。
- 一旦计算出前缀总和,就将每个值替换为取模M的值。
- 最终值相等的索引是和被M完全整除的范围。
- 找到相同值的最大范围。
下面是上述方法的实现,
// C++ implementation of the above approach.
#include
using namespace std;
// Function to find the maximum range
// whose sum is divisible by M.
pair maxrange(int n,
int a[], int m)
{
int pre[n + 5];
map > mpp;
int value, l, r, lans = -1,
rans = -1, ans = 0;
// Calculate the prefix sum
pre[0] = a[0];
for (int i = 1; i < n; i++) {
pre[i] = a[i] + pre[i - 1];
}
// Replacing the values with modulo M
// and inserting the indices into the map
for (int i = 0; i < n; i++) {
pre[i] = pre[i] % m;
mpp[pre[i]].insert(i);
}
// Calculate the range [L, R]
for (auto it = mpp.begin(); it != mpp.end(); it++) {
if (it->first == 0) {
value = *((it->second).rbegin()) + 1;
l = 1;
r = value;
}
else {
value = *((it->second).rbegin())
- *((it->second.begin()));
l = *((it->second.begin())) + 2;
r = *((it->second).rbegin()) + 1;
}
if (value > ans && l <= r) {
ans = value;
lans = l;
rans = r;
}
}
return make_pair(lans, rans);
}
// Driver code
int main()
{
int A[] = { 3, 7, 5, 2, 5, 10 };
int N = sizeof(A) / sizeof(A[0]);
int M = 3;
pair value = maxrange(N, A, M);
if (value.first == -1) {
cout << -1 << "\n";
}
else {
cout << value.first << " "
<< value.second << "\n";
}
return 0;
}
输出:
1 3