题目描述
众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 nn 个数,希望你从这 nn 个数中找到三个数,使得这三个数的和是 KK 的倍数,且这个和最大。数据保证一定有解。
输入描述
第一行包括 2 个正整数 n, Kn, K。
第二行 nn 个正整数,代表给定的 nn 个数。
其中,1≤n ≤105, 1≤K ≤1031≤n ≤105, 1≤K ≤103,给定的 nn 个数均不超过 108108。
输出描述
输出一行一个整数代表所求的和。
输入输出样例
示例
输入
4 3
1 2 3 4
输出
9
代码:
#include <stdio.h>
#include <stdlib.h>
// 函数:比较两个整数,返回较大的那个
int max(int a, int b) {
if (a > b)
return a;
else
return b;
}
// 函数:用于qsort函数的比较,按降序排序
int camp(const void* a, const void* b) {
return *(int*)b - *(int*)a;
}
int main() {
int i, j, m, n, k, sum = 0;
// 从标准输入中读取数组长度n和整数k
scanf("%d %d", &n, &k);
int a[n];
// 循环读取数组a中的元素
for (i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
// 对数组a进行降序排序
qsort(a, n, sizeof(a[0]), camp);
// 三重循环找到符合条件的最大和
for (i = 0; i < n - 2; i++) {
if ((a[i] + a[i + 1] + a[i + 2]) < sum)
break;
for (j = i + 1; j < n - 1; j++) {
if ((a[i] + a[j] + a[j + 1]) < sum)
break;
for (m = j + 1; m < n; m++) {
if ((a[i] + a[j] + a[m]) < sum)
break;
// 如果找到能被k整除的和,则更新sum
if (!((a[i] + a[j] + a[m]) % k)) {
sum = max(sum, a[i] + a[j] + a[m]);
break;
}
// 跳过重复的元素
while (a[m] == a[m + 1]) {
m++;
}
}
while (a[j] == a[j + 1]) {
j++;
}
}
while (a[i] == a[i + 1]) {
i++;
}
}
// 输出找到的最大和
printf("%d", sum);
return 0;
}