有两个数组a,b,大小都为n,;通过交换a,b中的元素,使sum(a)-sum(b)最小。
有两个数组a,b,大小都为n,数组元素的值任意整形数,无序;
要求:通过交换a,b中的元素,使数组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| - |A'| = |A| - |A-2x|
假设A > 0,
当x 在 (0,A)之间时,做这样的交换才能使得交换后的a和b的和之差变小,x越接近A/2效果越好,
如果找不到在(0,A)之间的x,则当前的a和b就是答案。
所以算法大概如下:
在a和b中寻找使得x在(0,A)之间并且最接近A/2的i和j,交换相应的i和j元素,重新计算A后,重复前面的步骤直至找不到(0,A)之间的x为止。
int sum1,sum2,a; //分别表示 a[]的和 b[]的和 以及2者之差
int temp;
bool dayu0; //和之差是否大于0
int pos1,pos2; //等待交换的a[i]和b[j]的下标 i j
float minn; //最接近a/2的a[i]-b[j]值
bool have1 ; //是否能有解
while (1)
{
sum1 = 0;
sum2 = 0;
for (int i = 0 ; i < n;++i) //求两个数组的和
{
sum1 += ar1[i];
sum2 += ar2[i];
}
a = sum1 - sum2; //和之差
dayu0 = a>0?true:false; //和之差是大于0还是小于0
have1 = false; //是否能找到解
for (int i = 0 ; i < n;++i) //找最接近a/2的 a[i]-b[j]
{
for (int j = 0;j < n;++j)
{
temp = ar1[i] - ar2[j];
if ((dayu0&&temp > 0&&temp < a)||(!dayu0&&temp < 0 && temp > a)) //如果a[i]-b[j] 在(0,a)之间 (超出的就没有意义了)
{
if (have1&&abs(temp - a/2.0) < minn) //若比之前的a[i]-b[j]更接近a/2 则更新
{
minn = abs(temp - a/2.0);
pos1 = i;
pos2 = j;
}
else
{
have1 = true;
minn = abs(temp - a/2.0);
pos1 = i;
pos2 = j;
}
}
}
}
if (!have1) //若找不到符合条件的a[i]-b[j]了 则结束
{
break;
}
swap(ar1[pos1],ar2[pos2]); //交换a b中的元素
}
有两个数组a,b,大小都为n,;通过交换a,b中的元素,使sum(a)-sum(b)最小。的更多相关文章
- 谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数。
谷歌笔试题--给定一个集合A=[0,1,3,8](该集合中的元素都是在0,9之间的数字,但未必全部包含), 指定任意一个正整数K,请用A中的元素组成一个大于K的最小正整数. Google2009华南地 ...
- 有两个数组a,b,大小都为n;通过交换a,b中的元素,使sum(a)-sum(b)最小。
今天在浏览网页的时候,发现了一个叫做 华为面试题(8分钟写出代码) 的链接,不确定真实性,纯属好奇,就点进去看看 这个可能是很老的题目吧,因为我看到这题目时,底下有好多评论了.提到XX排序,内存占用 ...
- 【编程题目】有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序;(需要回头仔细研究)
32.(数组.规划)有两个序列 a,b,大小都为 n,序列元素的值任意整数,无序:要求:通过交换 a,b 中的元素,使[序列 a 元素的和]与[序列 b 元素的和]之间的差最小.例如: var a=[ ...
- 75 int类型数组中除了一个数出现一次或两次以外,其他数都出现三次,求这个数。[2行核心代码]
[本文链接] http://www.cnblogs.com/hellogiser/p/single-number-of-array-with-other-three-times.html [题目] i ...
- 在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1)
题目:在一个数组中,除了两个数外,其余数都是两两成对出现,找出这两个数,要求时间复杂度O(n),空间复杂度O(1) 分析:这道题考察位操作:异或(^),按位与(&),移位操作(>> ...
- 使用KFold进行训练集和验证集的拆分,使用准确率和召回率来挑选合适的阈值(threshold) 1.KFold(进行交叉验证) 2.np.logical_and(两bool数组都是正即为正) 3.np.logical_not(bool数组为正即为反,为反即为正)
---恢复内容开始--- 1. k_fold = KFold(n_split, shuffle) 构造KFold的索引切割器 k_fold.split(indices) 对索引进行切割. 参数说明:n ...
- [LeetCode] Intersection of Two Arrays 两个数组相交
Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, 2, 1] ...
- leetcode 4 : Median of Two Sorted Arrays 找出两个数组的中位数
题目: There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the ...
- 包含MIN函数的栈+一个数组实现两个堆栈+两个数组实现MIN栈
1.题目描述 定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数. 思路:利用一个辅助栈来存放最小值 栈 3,4,2,5,1 辅助栈 3,2,1 每入栈一次,就与辅 ...
随机推荐
- ORACLE数据库闪回日志写满
网站页面无法显示完整.检查web服务是正常的,所以可能是ORACLE数据库出了问题. 首先检查闪回日志写满 然后检查归档日志文件写满的缘故了.使用以下几个命令可以看出当前归档日志文件的使用情况: se ...
- ubuntu zend-eclipse-php debugger调试
1 下载zendDebugger http://www.zend.com/en/products/studio/downloads?src=downloadb 在这个页面中找到zend debugge ...
- [CUDA] ubuntu14.04+cuda7.5下安装cudnn7.0
cuda:7.5 cudnn:cudnn-7.0-linux-x64-v4.0-prod.tgz cudnn样例:cuDNN v4 Code Samples 1. 解压 tar -zxvf cudnn ...
- softmax
void LogisticRegression_softmax(LogisticRegression *this, double *x) { int i; double max = 0.0; doub ...
- ArrayList 转换为DataTable
, }; ArrayList list = new ArrayList(arr); var dt = new DataTable(); DataColumn dc = new DataColumn(& ...
- 初学JqueryMobile(一)
一.初学2个data标签 标签名称 标签属性 属性说明 备注 data-role page 容器或试图 表示容器的作用 header 标题 content 内容 footer 页脚 data-tran ...
- ubuntu下php开发环境搭建,nginx+(cgi)php5fpm+memcached+xdebug
由于只是开发环境,所以都是选择比较简单的apt-get安装方式 ,但中间也遇到一点问题. 首先安装nginx nginx的安装和配置其实很简单,nginx本身非常轻量级, 直接 sudo apt-ge ...
- Lucene4.9学习笔记——Lucene建立索引
基本上创建索引需要三个步骤: 1.创建索引库IndexWriter对象 2.根据文件创建文档Document 3.向索引库中写入文档内容 这其中主要涉及到了IndexWriter(索引的核心组件,用于 ...
- 韦东山教程ARM的时钟设置出现的问题及其解决方法
时钟设置是一个非常重要的环节,如果系统没有合适的时钟,根本无法工作. S3C2440的时钟复杂,分为FCLK,HCLK,PCLK. 在程序测试中,曾出现这样一个错误.系统当前FCLK为400 ...
- Servlet的一些API使用介绍
final String rootPath = getServletConfig().getServletContext().getRealPath("/"); 获取项目运行的根 ...