本人第一次编写题解,如果有错误还请大家多多海涵 对于这道题,我们可以采用一种很巧妙的算法,即 “如果前i个数的前缀和与前j个数的前缀和(在对k取余之后)相等,则从i到j之间的数的和都为k的倍数”
using namespace std;
int main() {
int n, K;
cin >> n >> K;
vector<int> a(n);
for (int i = 0; i < n; ++i) {
cin >> a[i];
}
unordered_map<int, int>t;
t[0] = 0; // 初始化:前缀和为0的位置记为0(前0个元素)
int prefix = 0; // 当前前缀和的模
int max_len = 0;
for (int i = 1; i <= n; ++i) { // i表示前i个元素的前缀和(对应数组0..i-1)
// 累加当前元素并取模,确保结果非负
prefix = (prefix + a[i - 1]) % K;
// 若该模值已出现过,计算子数组长度
if (t.count(prefix)) {
max_len = max(max_len, i - t[prefix]);
} else {
// 首次出现,记录位置
t[prefix] = i;
}
}
cout << max_len << endl;
return 0;
}

京公网安备 11010502036488号