開啟章節選單
10125 Sumsets
題目連結
題目翻譯
給定一個整數集合 S,請找出最大的 d,使得存在集合中四個相異的元素 a、b、c、d,滿足 a + b + c = d。
輸入
有多組測資,每組第一行是整數 n(1 ≤ n ≤ 1000),代表集合大小,接下來 n 行是集合中的元素,每個元素互不相同,範圍在 -536870912 到 536870911 之間。輸入以 n = 0 結束。
輸出
每組測資輸出一行最大的 d;若不存在這樣的組合,輸出 no solution。
解題思路
先用雜湊表 (unordered_map) 把所有「兩數之和」v[i] + v[j](i ≠ j)記下來,對應儲存下標組合 (i, j)。接著再次枚舉 i、j(i ≠ j),計算差值 v[i] - v[j]:如果這個差值曾經是某兩個元素 v[k1] + v[k2] 的和,且 i、j、k1、k2 四個下標兩兩不同,就代表 v[k1] + v[k2] + v[j] = v[i],也就是找到了一組 a + b + c = d(其中 d = v[i])。用 mx 持續記錄所有合法解中最大的 v[i],最後若找不到任何合法組合則輸出 no solution。
程式碼
//author: Piau #include <bits/stdc++.h> using namespace std; #define pb push_back #define fi first #define se second #define INF LONG_LONG_MAX/1000 #define WA() cin.tie(0)->sync_with_stdio(0) #define int long long #define PII pair<int, int> signed main() { WA(); for (int n; cin >> n, n;) { vector<int> v(n); for (auto &i : v) cin >> i; unordered_map<int, vector<PII>> mp; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) continue; mp[v[i]+v[j]].pb({i, j}); } } int mx = -INF; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i == j) continue; if (mp.count(v[i]-v[j])) for (auto &k : mp[v[i]-v[j]]) { if (i != k.fi && i != k.se && j != k.fi && j != k.se) mx = max(mx, v[i]); } } } if (mx == -INF) cout << "no solution\n"; else cout << mx << '\n'; } }