题目描述
一个数组中有若干正整数,将此数组划分为两个子数组,使得两个子数组各元素之和a,b的差最小,对于非法输入应该输出ERROR。
输入
数组中的元素
输出
降序输出两个子数组的元素和
样例输入
10 20 30 10 10
10 20 abc 10 10
样例输出
40 40
ERROR
思路:先将字符串转换为数组,然后将求得数组之和一半half,回溯法不断逼近half。
#include <cstdio>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
int num[1010];
int idx;
bool flag;
int allSum, half, a;
void init() {
idx = 0;
flag = true;
allSum = 0;
half = 0;
a = 0;
}
void DFS(int i, int sum) {
if (i == idx) {
return;
} else if (num[i] + sum <= half) { //不断逼近half,但不能超过
a = max(num[i] + sum, a);
if (a == half) return;
DFS(i + 1, num[i] + sum);
}
DFS(i + 1, sum);
}
int main() {
string s;
while (getline(cin, s)) {
init();
int len = s.length();
for (int i = 0; i < len; ++i) {
if (s[i] == ' ')
continue;
else {
int x = s[i] - '0';
if (s[i] <= '9' && s[i] >= '0') { //字符串转换为数字
int j = i + 1;
int temp = 0;
temp = temp * 10 + x;
while (s[j] <= '9' && s[j] >= '0') {
x = s[j] - '0';
temp = temp * 10 + x;
++j;
}
num[idx++] = temp;
i = j;
} else {
flag = false; // 非法
}
}
}
if (!flag) {
printf("ERROR\n");
} else {
for (int i = 0; i < idx; ++i) {
allSum += num[i];
}
half = allSum / 2;
DFS(0, 0);
printf("%d %d\n", allSum - a, a);
}
}
return 0;
}