描述
对于给定的 n 个整数 a1,a2,...,an,将其分为 a,b 两个数组,满足:
∙ ∙所有 5 的倍数元素均在 a 数组中;
∙ ∙所有 3 的倍数元素(不包括 5 的倍数)均在 b 数组中;
∙ ∙其他元素可以任意分配。
求解是否存在一种分配方案,使得 a 数组中各个元素之和等于 b 数组中各个元素之和。每一个元素要么在 a 数组中,要么在 b 数组中;数组可以为空,此时和为 0。如果存在这样的方案,输出 true,否则输出 false。
输入描述:
第一行输入一个整数 n(1≦n≦30)代表给定的整数个数。
第二行输入 n 个整数 a1,a2,...,an(−500≦ai≦500)。
保证数据随机生成。
输出描述:
如果存在满足条件的分配方案,输出 true,否则输出false。
示例1
输入:
4
1 5 -5 1
输出:
true
说明:
在这个样例中,a 数组可以为 {5,−5,1},b 数组可以为 {1},满足条件。
示例2
输入:
3
3 5 8
输出:
false
cpp
#include<iostream>
#include<algorithm>
#include<vector>
#include<unordered_set>
using namespace std;
int main(){
int n;
while(cin >> n){
vector<int> arr;
int sum3 = 0;
int sum5 = 0;
int rest = 0;
for(int i = 0; i < n; i++){
int x;
cin >> x;
if(x % 5 == 0) //先求一个组的和
sum5 += x;
else if(x % 3 == 0) //再求另一个组的和
sum3 += x;
else{
arr.push_back(x); //剩余的加入数组并求和
rest += x;
}
}
unordered_set<int> s1, s2;
s1.insert(0); //枚举所有组合的不重复和,0为空数组
for(int i = 0; i < arr.size(); i++){ //遍历每一个数字
s2 = s1; //每个数字都要与当前集合的每个数相加组成新的和
for(auto it: s2)
s1.insert(it + arr[i]);
}
bool flag = false;
for(auto it: s1){ //遍历枚举的集合
if(it + sum5 == sum3 + rest - it){ //分成两部分后相等
flag = true;
break;
}
}
cout << (flag ? "true" : "false") << endl;
}
return 0;
}