题意:
给出一个长度为N的无序数组,数组中的元素为整数,有正有负包括0,并互不相等。从中找出所有和 = 0的3个数的组合。如果没有这样的组合,输出No Solution。如果有多个,按照3个数中最小的数从小到大排序,如果最小的数相等则按照第二小的数排序。
思路:
利用map存储每个数的下标,枚举其中两个数,然后O(logn)时间查询第三个数,并且用一个long long数字保存三个数下标Hash值避免重复
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1005;
int a[MAXN], b[5];
struct node {
int x, y, z;
bool operator < (const node &c) const {
if (x == c.x) {
if (y == c.y) return z < c.z;
return y < c.y;
}
return x < c.x;
}
};
bool cmp(const int x, const int y) {
return a[x] < a[y];
}
int main() {
int n;
scanf("%d", &n);
map <int, int> mp;
set <ll> st;
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
mp[a[i]] = i;
}
vector <node> ans;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (j == i) continue;
int tt = mp[-a[i]-a[j]];
if (tt > 0 && tt != i && tt != j) {
b[0] = i; b[1] = j; b[2] = tt;
sort(b, b + 3, cmp);
ll x = b[0] * 100000000 + b[1] * 10000 + b[2];
if (st.find(x) != st.end()) continue;
ans.push_back((node){a[b[0]], a[b[1]], a[b[2]]});
st.insert(x);
}
}
}
if (ans.empty()) {
puts("No Solution");
return 0;
}
sort (ans.begin(), ans.end());
for (int i = 0; i < (int)ans.size(); i++)
printf("%d %d %d\n", ans[i].x, ans[i].y, ans[i].z);
return 0;
}