首先我们观察到存在 a[i] == 0 时,一定输出 "NO"
排除掉 a[i] == 0 的情况后,我们可以发现,a[i] 不是正就是负
我于是定性地画出了 “图像”
我们可以把正数分一个组,负数分一个组
可以想到没有正数或是没有负数时,不可能 存在和为 0 的情况
之后就是判断 交界处两个数加起来 可不可能 不为 0
假设 正数组中存在一个数 a,负数组中存在一个数 b,满足 a + b == 0
我们要想办法避免这种情况,就想着把 a 或 b 替换掉,然而当正数或负数不同的数量超过 1 时,我们就有可供选择的其他数 (alternatives),使交界处的和不为 0,此时我们已经完成了构造
也就是 当只有一种正数和一种负数,且这两个数和为 0 时,才能满足 "NO" 的条件,我们可以直接判掉
剩下来的直接输出 "YES"
本题,我使用了两个 set 维护,当然也可以使用 4 个 bool 变量记录,此处不再赘述
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
unordered_set<int> zh, fu; // 正数、负数 set
bool bl = false; // 特判是否存在 0
for (int i = 0; i < n; ++i) {
int tmp;
cin >> tmp;
if (!bl) { // 已经存在 0,就直接忽略后面的操作,只要读完数据就行
if (tmp == 0) {
bl = true;
} else if (tmp > 0) {
zh.emplace(tmp);
} else {
fu.emplace(tmp);
}
}
}
if (bl) { // 有 0 直接输出 NO
cout << "NO";
return 0;
}
int s = zh.size(), t = fu.size();
if (s == 0 || t == 0) { // 先判空,防止 *zh.begin() 或 *fu.begin() 为空
cout << "YES";
return 0;
}
int a = *zh.begin(), b = *fu.begin();
if (zh.size() == 1 && fu.size() == 1 && a + b == 0) {
cout << "NO";
return 0;
}
cout << "YES"; // 其余情况都是 YES
}

京公网安备 11010502036488号