a元素的和b元素的和之间的差最小

来源:互联网 发布:caxa怎样编程 编辑:程序博客网 时间:2024/05/16 08:55
32.(数组、规划)
有两个序列a,b,大小都为n,序列元素的值任意整数,无序;
要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
例如:  
var a=[100,99,98,1,2, 3];
var b=[1, 2, 3, 4,5,40];


思路一:迭代法。O(n^2)搜索时间,当然可以先排序,在用二分法查找另一元素,可将复杂度降为O(nlogn)

思路二:将a、b合为一个数组,然后任意取6个数字,和为S6,使得|S12-2*S6|最小

//coder:Lee,20120320


#include<iostream>
#include<cassert>
using namespace std;
void Swap(int *a,int *b)
{
*a=*a^*b;
*b=*a^*b;
*a=*a^*b;
}
int  ABDiffMin(int *A,int *B,int length)
{
assert(A!=NULL&&B!=NULL&&length>0);
int Sa=0,Sb=0;
for (int i=0;i<length;i++)
{
Sa+=A[i];
Sb+=B[i];
}
int minDiff=abs(Sa-Sb);
int newDiff;
int k=0;
do 
{
int swapIndexA,swapIndexB;
newDiff=minDiff;
for(i=0;i<length;i++)
{
for (int j=0;j<length;j++)
{
int tempDiff=abs(Sa-Sb-2*(A[i]-B[j]));
if (tempDiff<newDiff)
{
newDiff=tempDiff;
swapIndexA=i;
swapIndexB=j;
}
}
}


cout<<"Sa,Sb"<<Sa<<" "<<Sb<<endl;
cout<<"after:"<<endl;
for(i=0;i<length;i++)
{
cout<<A[i]<<" ";
}
cout<<endl;
for(i=0;i<length;i++)
{
cout<<B[i]<<" ";
}cout<<endl;
cout<<"newDiff"<<newDiff<<endl;
cout<<"minDiff"<<minDiff<<endl;
if(newDiff<minDiff)
{
minDiff=newDiff;
Sa=Sa-A[swapIndexA]+B[swapIndexB];
Sb=Sb-B[swapIndexB]+A[swapIndexA];
Swap(&A[swapIndexA],&B[swapIndexB]);
}
else
break;
} while (1);
return newDiff;
}
int main()
{
int A[]={100,99,98,1,2, 3};
int B[]={1, 2, 3, 4,5,40};
int length=sizeof(A)/sizeof(int);
cout<<"diff:"<<ABDiffMin(A,B,length)<<endl;
for(int i=0;i<length;i++)
{
cout<<A[i]<<" ";
}
cout<<endl;
for(i=0;i<length;i++)
{
cout<<B[i]<<" ";
}
return 0;


}