码迷,mamicode.com
首页 > 编程语言 > 详细

有两个数组a,b,大小都为n,数组元素的值任意整形数,无序,通过交换a,b中的元素,使得|sum(a)-sum(b)|最小

时间:2015-08-09 16:53:12      阅读:1239      评论:0      收藏:0      [点我收藏+]

标签:

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

令A=sum(a)-sum(b)

a的第i个元素和b的第j个元素交换后,a和b的和之差为

A‘= sum(a) - a[i] + b[j] - (sum(b) - b[j] + a[i])
           = sum(a) - sum(b) - 2 (a[i] - b[j])
           = A - 2 (a[i] - b[j])

设x = a[i] - b[j]

只有当|A-2x|<|A|,调换a[i]和b[j]才有意义,此时的条件为:

0<x<A,A>0或者A<x<0,A<0,如果找不符合这样条件的x,则结束调换。

并且当x越接近A/2,效果越好(A‘趋近于0)。

所以算法大概如下:

    在a和b中寻找两个数a[i],b[j]使得0<x<A,A>0或者A<x<0,A<0,并且最接近A/2的i和j,交换相应的i和j元素,重新计算A后,重复前面的步骤直至找不到符合0<x<A,A>0或者A<x<0,A<0的a[i],b[j]为止。

代码如下:

#include<iostream>
using namespace std;
void minSumDiff(int a[],int b[],int n)
{
    bool unfinish=true;
    while(unfinish)
    {
        unfinish=false;
        int sumDiffab=0;//存储sum(a)-sum(b)=A
        for(int i=0;i<n;i++)
            sumDiffab+=a[i]-b[i];
        float halfSum=sumDiffab/2.0;//即A/2
        int posa=0,posb=0;
        float mindis=abs(sumDiffab);
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<n;j++)
            {
                int x=a[i]-b[j];
                if((sumDiffab>0&&x>0&&x<sumDiffab)||(sumDiffab<0&&x<0&&x>sumDiffab))//if(x*sumDiffab>0&&abs(x)<abs(sumDiffab))
                    //只有满足|A-2x|<|A|,调换才有意义:即A>0时,0<x<A;当A<0时,A<x<0
                {
                    unfinish=true;
                    float t=abs(x-halfSum);//计算x与A/2的距离
                    if(t<mindis)//存储离A/2最近的x的距离值以及对应的调换。
                    {
                        mindis=t;
                        posa=i;
                        posb=j;
                    }
                }
            }
        }
        if(unfinish)
        {
            int tmp;
            tmp=a[posa];
            a[posa]=b[posb];
            b[posb]=tmp;
        }
    }
}
int main()
{
    int a[]={4,3,9};
    int b[]={2,1,6};
    minSumDiff(a,b,3);
    for(int i=0;i<3;i++)
    {
        cout<<a[i]<<","<<b[i]<<endl;
    }
    system("pause");
    return 0;
}

 

有两个数组a,b,大小都为n,数组元素的值任意整形数,无序,通过交换a,b中的元素,使得|sum(a)-sum(b)|最小

标签:

原文地址:http://www.cnblogs.com/xiangzhi/p/4715262.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!