# 倍数问题 **题目描述** 众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。 **输入格式** 从标准输入读入数据。 第一行包括 2 个正整数 n, K。 第二行 n 个正整数,代表给定的 n 个数。 **输出格式** 输出到标准输出。 输出一行一个整数代表所求的和。 **样例输入** ``` 4 3 1 2 3 4 ``` **样例输出** ``` 9 ``` **样例解释** ``` 选择2、3、4。 ``` 以下错误的一项是? ## aop ### before ```c #include using namespace std; ``` ### after ```c ``` ## 答案 ```c #define ll long long using namespace std; const int maxx = 1e5 + 100; const int maxm = 1e3 + 100; int a[maxx]; vector p[maxm]; int n, k; bool cmp(int a, int b) { return a > b; } int main() { scanf("%d%d", &n, &k); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); p[a[i] % k].push_back(a[i]); } for (int i = 0; i < k; i++) sort(p[i].begin(), p[i].end(), cmp); int _max = 0; for (int i = 0; i < k; i++) { if (p[i].size() == 0) continue; if ((3 * i == k || i == 0) && p[i].size() >= 3) _max = max(_max, p[i][0] + p[i][1] + p[i][2]); for (int j = 0; j < k; j++) { if (!p[j].size()) continue; int z = k - (i + j) % k; if (z < 0) continue; if (z == i && z == j) continue; else if ((i != j) && (z == i || z == j) && p[z].size() >= 2) _max = max(_max, p[i][0] + p[j][0] + p[z][1]); else if (i == j && p[i].size() >= 2 && p[z].size() >= 1) _max = max(_max, p[i][0] + p[j][1] + p[z][0]); else if (i != j && i != z && j != z && p[i].size() >= 1) _max = max(_max, p[i][0] + p[j][0] + p[z][0]); } } printf("%d\n", _max); return 0; } ``` ## 选项 ### A ```c #define FOR0(a, b) for (int i = a; i < b; ++i) #define FORE(a, b) for (int i = a; i <= b; ++i) typedef long long ll; typedef pair pii; ll dp[2][4][1005]; int n, k, a[100005], v[100005]; int main() { scanf("%d%d", &n, &k); for (int i = 1; i <= n; ++i) { scanf("%d", &a[i]); v[i] = a[i]; v[i] %= k; } memset(dp, -0x3f3f3f3f, sizeof dp); dp[0][0][0] = 0; int d = 0; for (int i = 1; i <= n; ++i) { for (int j = 0; j < k; ++j) { for (int p = 0; p <= 3; ++p) { if (i < p) continue; dp[d ^ 1][p][j] = max(dp[d ^ 1][p][j], dp[d][p][j]); if (p > 0) dp[d ^ 1][p][j] = max(dp[d ^ 1][p][j], dp[d][p - 1][((j - v[i]) % k + k) % k] + a[i]); } } d ^= 1; } cout << dp[d][3][0] << endl; return 0; } ``` ### B ```c int n, k, ans = 0; int temp[3], num[100005], vis[100005] = {0}; void dfs(int s) { if (s == 3) { int t = temp[0] + temp[1] + temp[2]; if (t % k == 0 && t > ans) ans = t; return; } else { for (int i = 0; i < n; i++) { if (!vis[i]) { temp[s] = num[i]; vis[i] = 1; dfs(s + 1); vis[i] = 0; } } } } int main() { scanf("%d%d", &n, &k); for (int i = 0; i < n; i++) scanf("%d", &num[i]); dfs(0); printf("%d\n", ans); return 0; } ``` ### C ```c int N, k; int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cin >> N >> k; vector> vec(k, vector(3, -1)); for (int i = 0; i < N; ++i) { int temp; cin >> temp; int y = temp % k; if (temp > vec[y][0]) { vec[y][2] = vec[y][1]; vec[y][1] = vec[y][0]; vec[y][0] = temp; } else if (temp > vec[y][1]) { vec[y][2] = vec[y][1]; vec[y][1] = temp; } else if (temp > vec[y][2]) vec[y][2] = temp; } vector ans(3); int result = 0; for (int i = 0; i < k; ++i) for (int j = i; j < k; ++j) { int r = (k - i + k - j) % k; ans[0] = vec[i][0]; if (i == j) { ans[1] = vec[i][1]; if (r == i) ans[2] = vec[i][2]; else ans[2] = vec[r][0]; } else { ans[1] = vec[j][0]; if (r == i) ans[2] = vec[i][1]; else if (r == j) ans[2] = vec[j][1]; else ans[2] = vec[r][0]; } if (ans[0] != -1 && ans[1] != -1 && ans[2] != -1 && ans[1] + ans[2] + ans[0] > result) result = ans[1] + ans[2] + ans[0]; } cout << result; } ```