Description
已知N个不同的数a[1..N]。
求能否从这些数中选出不同的三个数A、B、C,使得他们的和为S。
Input
多组数据,每组数据第一行有两个个整数N和S。(1 <= N <= 1000, 1 <= S <= 3*10^8)
第二行有N个整数a[1], a[2], ..., a[n]。 (1 <= a[i] <= 10^8)
Output
对于每组数据,如果可以,输出”YES”,否则输出”NO”,并换行。
Sample Input
4 6
1 2 3 4
3 5
2 3 4
1 2 3 4
3 5
2 3 4
Sample Output
YES
NO
NO
#include <bits/stdc++.h>
const int N = 1005;
int a[N];
int n, s;
//排序后枚举前两个数对第三个数进行二分
int main() {
while (~scanf("%d%d", &n, &s)) {
for (int i = 0; i < n; ++i) scanf("%d", a + i);
std::sort(a, a + n); //进行排序,利于减少复杂度
bool ok = 0; //用来标记结果
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) { //前俩个数字用枚举
int c = s - a[i] - a[j]; //第三个数字就用二分
int p = std::lower_bound(a + j + 1, a + n, c) - a;
//函数lower_bound()在first和last中的<strong>前闭后开</strong>区间进行二分查找,返回大于或等于val的<strong>第一个元素</strong>位置。如果所有元素都小于val,则返回<strong>last</strong>的位置
if (p > j && p < n && a[p] == c) { //对p进行无误判断
ok = 1;
}
}
}
puts(ok == 1 ? "YES" : "NO"); //根据ok,输出结果
}
return 0;
}