编程挑战(5)
1: 问题的提出:
有两个数组a,b,大小都为n, 数组元素的值任意,无序。
要求:通过交换a,b中的元素,使数组a元素的和与数组b元素的和之间的差最小
2:问题的转化
2.1 求这2n个数据相加之和,然后再计算出和的一半。
2.2 枚举出从2n个数字中取出n的的各种组合,分别求出每种组合的和。
2.3 将每种组合的和与一半2.1的结果比较,相差最小即为最后结果
其实问题最后转化为编程挑战(4),数组中元素的组合
//数组递归求和 int sum(int value[], int length) { int result = 0; if (length == 1) { result = value[0]; } else { result = value[length - 1] + sum(value, length - 1); } return result; } //合并两个数组为一个数组 void contact(int value1[], int length1, int value2[], int length2, int value3[], int&length3) { length3 = 0; for(int i=0; i<length1; i++) { value3[length3++] = value1[i]; } for(int i=0; i<length2; i++) { value3[length3++] = value2[i]; } } //数组顺序输出 void output(int value[], int length, int average) { int sum = 0; for(int i=length -1 ; i>=0; i--) { sum = sum + value[i]; printf("%d ", value[i]); } printf("sum=%d average=%d abs(diff)=%d \n", sum, average, abs(sum - average)); } //数组顺序输出 void output(int value[], int length, int average) { int sum = 0; for(int i=length -1 ; i>=0; i--) { sum = sum + value[i]; printf("%d ", value[i]); } printf("sum=%d average=%d abs(diff)=%d \n", sum, average, abs(sum - average)); } //从M 个数中取 N 个数的组合,并求出每种情况的和与平均的差 void enumkind(int value[], int M, int N, int result[], int constant, int average) { for(int i = M; i >= N; i--) { result[N - 1] = value[i - 1]; if (N > 1) { enumkind(value, i - 1, N - 1, result, constant, average); } else { output(result, constant, average); } } } int _tmain(int argc, _TCHAR* argv[]) { int value1[4] = {10,25,38,49}; int length1 = 4; int value2[4] = {34,98,76,12}; int length2 = 4; int value3[8]; int length3 = 0; contact(value1, 4, value2, 4, value3, length3); printf("output all kinds of 4 elements\n"); int result[4]; int average = sum(value3, 8)/2; enumkind(value3, 8, 4, result, 4, average); getchar(); return 0; }