有两个序列a,b,大小都为 n,序列元素的值任意整数,无序 通过交换a,b中的元素,使序列 a的和与序列b的和之间的差最小

   网上看了许多解决方式,不是本身就是错的,就是代码写的真不敢恭维,以下代码由一个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 
*/


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值