题目描述
小明拥有一个大小为 NN 集合 SS,SS 中的元素依次为 s1,s2,...,sns1,s2,...,sn。
给出一个数 XX,请你判断是否能从 SS 中挑选任意个元素使得它们的和为 XX。
输入描述
第一行输入两个正整数 N,XN,X。
接下来一行包含 NN 个整数,s1,s2,...,sns1,s2,...,sn,表示集合的元素。
1≤N≤361≤N≤36,1≤si≤10161≤si≤1016,1≤X≤10161≤X≤1016。
输出描述
输出共 TT 行,每行表示一组数据的答案。
若可以拼凑出 XX 则输出 Y
,否则输出 N
。
输入输出样例
示例 1
输入
3 6
1 3 5
输出
Y
示例 2
输入
3 7
1 2 3
输出
N
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
#define int long long
unordered_set<int> generate(const vector<int>& nums, int l, int r) {
unordered_set<int> sums;
sums.insert(0);
for (int i = l; i <= r; i++) {
unordered_set<int> temp;
for (int s : sums) {
temp.insert(s);
temp.insert(s + nums[i]);
}
sums = temp;
}
return sums;
}
signed main() {
int n, x;
cin >> n >> x;
vector<int> a(n);
for (int i = 0; i < n; i++) cin >> a[i];
// 分治处理
int mid = n / 2;
auto left = generate(a, 0, mid - 1);
auto right = generate(a, mid, n - 1);
for (int s : left) {
if (right.count(x - s)) {
cout << "Y" << endl;
return 0;
}
}
cout << "N" << endl;
return 0;
}