給定 m 個整數和模數 p,從中選兩個數 a, b(可相同),使 (a + b) mod p 最大。m ≤ 100,000,多測試用例。
若 a + b < p,則 (a+b) mod p = a+b,最大值為最大的兩數之和。
若 a + b ≥ p,則 (a+b) mod p = a+b-p,我們希望 a+b 盡可能接近 2p-2(即 a+b-p 接近 p-2),但更直接的目標是使 a+b 在 [p, 2p-2] 區間內盡可能大,使餘數最大。
sort(a, a+m);
if (a[m-1] + a[m-2] < p) {
cout << a[m-1] + a[m-2] << '\n';
continue;
}
int ans = 0;
int j = 0;
for (int i = m-1; i >= 1; i--) {
while (j < i && a[i] + a[j] < p) j++;
if (j < i) ans = max(ans, a[i] + a[j] - p);
if (j > 0) ans = max(ans, a[i] + a[j-1]);
if (ans == p-1) break; // 理論最大值,提前結束
}
cout << ans << '\n';
本題將模運算最大值轉化為有序數組中雙指針尋找最佳配對。關鍵在於:排序後,對每個大數 a[i],最佳搭檔 a[j] 單調遞增,雙指針可線性掃描。注意提前剪枝(達到 p-1 即最優)。