网上看了许多解决方式,不是本身就是错的,就是代码写的真不敢恭维,以下代码由一个Java的解法转换而来比较清晰,亲测可用。
有两个序列a,b,大小都为n,序列元素的值任意整数,无序;要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和之间的差最小。
例如:
var a=[100,99,98, 1, 2, 3];
var b=[1, 2, 3, 4, 5, 40];
#include <stdio.h>
#include <limits.h>
#include <math.h>
typedef unsigned int boolean;
#define true 1
#define false 0
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
int sumArray(int a[], int n)
{
int i, count=0;
for(i=0; i<n; i++)
count += a[i];
return count;
}
void minDiff(int a[], int b[], int n)
{
if(ARRAY_SIZE(a) != ARRAY_SIZE(b))
return;
//get the summations of the arrays
int sum1 = sumArray(a, n);
int sum2 = sumArray(b, n);
if (sum1 == sum2) return;
//we use big array to denote the array whose summation is larger.
int *big = b;
int *small = a;
if (sum1 > sum2) {
big = a;
small = b;
}
// the boolean value "shift" is used to denote that whether there exists
// a pair of elements, ai and bj, such that (ai-bj) < diff/2;
boolean shift = true;
int diff = 1;
while (shift == true && diff > 0) {
shift = false;
diff = sumArray(big, n) - sumArray(small, n);
if (diff < 0) return;
int maxDiff = INT_MAX;
//pa and pb records the switch position
int pa = -1;
int pb = -1;
//the two for loops are used to find the pair of elements ai and bj
//such that (ai-bj) < diff/2 when sum(a) > sum(b).
int i = 0, j = 0;
for (i = 0; i <n; i++) {
for (j = 0; j < n; j++) {
if (big[i] > small[j]) {
int tempDiff = abs(diff - 2 * (big[i] - small[j]));
//the condition "tempDiff < diff" is very important, if such condition holds,
//we can switch the elements to make the difference smaller
//otherwise, we can't, and we should quit the while loop
if (tempDiff < maxDiff && tempDiff < diff) {
shift = true;
maxDiff = tempDiff;
pa = i;
pb = j;
}
}
}
}
if (shift == true) {
int temp = big[pa];
big[pa] = small[pb];
small[pb] = temp;
}
}
}
void printArray(int a[], int n)
{
int i = 0;
for(i = 0;i < n; i++)
printf("%d ", a[i]);
printf("\n");
return;
}
int main(void)
{
int a[] = {100, 99, 98, 1, 2, 3};
int b[] = { 1, 2, 3, 4, 5, 40};
minDiff(a, b, ARRAY_SIZE(a));
printArray(a, ARRAY_SIZE(a));
printArray(b, ARRAY_SIZE(b));
return 0;
}
/*
打印
1 99 98 1 2 2
100 3 3 4 5 40
*/