博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通过交换 a,b 中的元素,使[序列 a 元素的和]与[序列 b 元素的和]之间的差最小。...
阅读量:7193 次
发布时间:2019-06-29

本文共 1253 字,大约阅读时间需要 4 分钟。

hot3.png

题目:

有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序;

要求:

通过交换 a,b 中的元素,使[序列 a 元素的和]与[序列 b 元素的和]之间的差最小。

例如:

var a = [100,99,98,1,2, 3];
var b = [1, 2, 3, 4,5,40];

最后的结果为:

var a = [1,99,98,1,2,2];

var b = [100, 3,3,4,5,40];

分析:

最简单的方法应该就是暴力穷举

这里阐述在网上看到的另一种方法:

对于序列a和b,令A = sum(a) - sum(b)

分别用i,j遍历a,b序列,若a[i]和b[j]交换

则: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])

即就是:(a[i] - b[j])在(0,A)之间并且最接近A/2则序列a,b的差值最小

因此得到算法:

在a和b中寻找使得x在(0,A)之间并且最接近A/2的i和j,交换相应的i和j元素,重新计算A后,重复前面的步骤直至找不到(0,A)之间的x为止。

代码实现:

(GCC编译通过)

#include "stdio.h"#include "stdlib.h"void balanceArray(int a[],int b[],int n);int sumArray(int a[],int n);int main(void){	int i;	int a[5]={0,1,2,3,4},b[5]={5,6,7,8,9};	balanceArray(a,b,5);		for(i=0;i<5;i++)		printf("%3d",a[i]);	printf("\n");		for(i=0;i<5;i++)		printf("%3d",b[i]);			printf("\n");	return 0;}void balanceArray(int a[],int b[],int n){	int *p,*q;	int i,j,itemDValue,sumDValue,tmp,flag=1;		if(sumArray(a,n) < sumArray(b,n))	{		p = b;		q = a;	}		while(flag)	{		flag=!flag;		for(i=0;i
 0)) { flag=!flag; tmp = p[i]; p[i] = q[j]; q[j] = tmp; } } } }}int sumArray(int a[],int n){ int i,count=0; for(i=0;i

转载于:https://my.oschina.net/u/1470003/blog/266255

你可能感兴趣的文章
L2-001. 紧急救援(迪杰斯特拉算法)
查看>>
leetcode297. 二叉树的序列化与反序列化
查看>>
bzoj3272 3638
查看>>
bzoj3192
查看>>
Controlled Tournament(状态压缩DP)
查看>>
Mac下,如何把项目托管到github
查看>>
记微软OpenHack机器学习挑战赛
查看>>
new XSSFWorkbook(is); Package should contain a content type part [M1.13]
查看>>
MongoDB安全及身份认证
查看>>
oc精简笔记
查看>>
python的多线程和守护线程
查看>>
traditional:true
查看>>
PS字体加粗的小方法、、
查看>>
构造水题 Codeforces Round #206 (Div. 2) A. Vasya and Digital Root
查看>>
友元程序集
查看>>
Mysql表编辑
查看>>
规定密码以字母开头只能包含字母、数字和下划线
查看>>
计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task
查看>>
maven下载及安装
查看>>
svn安装
查看>>