一个数组中有若干正整数,将此数组划分为两个子数组,使得两个子数组各元素之和a,b的差最小,对于非法输入应该输出ERROR。
输入描述:
数组中的元素
输出描述:
降序输出两个子数组的元素和
示例1
输入
复制
10 20 30 10 10
10 20 abc 10 10
输出
复制
40 40
ERROR
AC代码:
#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#pragma warning(disable:4996)
using namespace std;
#include<string>
#include<vector>
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<list>
#include<unordered_map>
#include<unordered_set>
const int maxn = 10000 + 10;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const double pi = acos(-1.0);
const int sqrtn = 316;
int arr[maxn], idx = 1, sum = 0, first = 0;
//选出若干数,使他们的和最接近sum/2,但不要超过。dfs选or不选,
//若当前和+arr[i]不超过sum/2,选or不选
//若当前和+arr[i]超过sum/2,一定不选
//fisrt==sum/2或i==idx时结束
bool judge(string s) {//分割字符串为数组
int tmp = 0;
for (int i = 0; i < s.size(); i++) {
if (!isdigit(s[i]) && s[i] != ' ')return false;
else if (isdigit(s[i])) {
tmp = tmp * 10 + (s[i] - '0');
}
else if (s[i] == ' ') {
arr[idx++] = tmp;
sum += tmp;
tmp = 0;
}
}
return true;
}
void dfs(int i, int now) {
if (i == idx)return;
else if (now + arr[i] <= sum / 2) {
first = max(first, now + arr[i]);
if (first == sum / 2)return;
dfs(i + 1, now + arr[i]);
}
dfs(i + 1, now);//不选当前数
}
int main() {
string s;
while (getline(cin, s)) {
memset(arr, 0, sizeof(arr));
idx = 1;
sum = 0;
first = 0;
s += ' ';
if (judge(s) == false) {
printf("ERROR\n");
}
else {
dfs(1, 0);
printf("%d %d\n", sum - first, first);
}
}
return 0;
}