两个数组a[n],b[n]重新排列后,两数组的和的差最小

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

如:int a[6]={1,3,4,5,20};  int b[6]={6,30,8,9,10}; 运算后 a[6]={10,9,4,5,20,0};

思想:1)首先求出a数组元素之和与b数组元素之和的差的绝对值。

          2)用a中元素替换b中任意一个元素,重新计算其差的绝对值,如果绝对值小于原来的,则实现元素的交换。

         3)重复上述步骤直到不能交换

具体代码实现:

# include <iostream>
using namespace std;
int  swap(int * a,int sizea,int *b,int sizeb)
{
	int suma=0,sumb=0;

	for(int ai=0;ai<sizea;ai++)//求数组a的和
	{
		suma+=a[ai];
	}
	for(int bj=0;bj<sizeb;bj++)//求数组b的和
	{
		sumb+=b[bj];
	}
	int abssum=abs(suma-sumb),abstemp;//和的差的绝对值
	for(ai=0;ai<sizea;ai++)
		
	{   
		bool flag=false;//是否能交换
		while(true)
		{
			for(bj=0;bj<sizeb;bj++)
			{
                 
				  abstemp=abs((suma+b[bj]-a[ai])-(sumb-b[bj]+a[ai]));//用a中元素替换b中的元素
				  if(abstemp<abssum)
				  {
                        suma+=b[bj]-a[ai];
						sumb+=a[ai]-b[bj];
						abssum=abstemp;
						int temp=a[ai]; //交换a[ai]和b[ai]
						a[ai]=b[bj];//
						b[bj]=temp;
						flag=true; 
						break;// 由于发生了交换a,b中的元素都发生了变换,所以跳出bj的for循环,重新开始与b中元素替换

				  }

			}
			if(bj>=sizeb) //结束里层for循环,换下一个a[ai]
				break;
		}
	//如果有交换,且ai的值为最后一个元素,  
   //那么我们必须重新再来一遍,直到没有元素交换为止.
    //重新验证如果没有也可以
	//	if((ai==sizea-1)&&flag)
		//{
			//flag=false;
			//ai=-1;
	//	}
	}
	return abssum;
	
}
void s(int * a,int *b)
{
	a[0]=0;
		int sizea=sizeof(a)/sizeof(a[0]);
		cout<<sizea<<endl;
}
int main()
{
	int a[6]={10, 50, 30, 1, 20, 3};
	int b[6]={100, 2, 35, 4, 5, 40};  
int c=	swap(a,6,b,6);
cout<<c<<endl;
for(int i=0;i<6;i++)
cout<<a[i]<<" ";
cout<<endl;
for( i=0;i<6;i++)
cout<<b[i]<<" ";
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个比较经典的问题,可以使用贪心算法来解决。 首先,我们需要遍历数组 a 和数组 b,记录它们中 1 的个数的值。如果这个值为奇数,那么无论怎么操作,数组 a 都无法完全等于数组 b,因为每次操作都会使 1 的个数增加或减少 2,而奇数的值无法通过操作变成偶数。 如果这个值为偶数,那么我们可以进行如下操作: 1. 记录数组 a 中和数组 b 相同位置上都为 1 的个数,记为 count。 2. 对于数组 a 中和数组 b 不相同位置上都为 1 的位置,我们可以将它们按照从小到大的顺序配对,每次操作都可以将一对数都取反,这样可以使这两个位置上的数都变成 0,同时也不会影响 count 的值。 3. 如果此时 count 的值小于等于剩下的 1 的个数的一半,那么我们可以将这些剩下的 1 都取反,使它们变成 0,同时也不会影响 count 的值。这样就可以使数组 a 和数组 b 完全相等。 因此,最小的操作次数就是数组 a 和数组 b 中 1 的个数的值除以 2。 代码实现如下: ```python def min_operations(a, b): diff = sum(a[i] != b[i] for i in range(len(a))) if diff % 2 == 1: return -1 count = sum(a[i] == b[i] == 1 for i in range(len(a))) return diff // 2 - min(count, diff // 2) ``` 其中,a 和 b 分别表示两个数组,返回值为最小的操作次数。如果无法使数组 a 和数组 b 完全相等,则返回 -1。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值