一个面试题
来源:互联网 发布:ipad淘宝微淘在哪查看 编辑:程序博客网 时间:2024/06/05 22:31
今天看到一个题目:
有两个数组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为止。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/kittyjie/archive/2009/07/28/4386742.aspx
根据这个思路,用C++实现了一下,代码如下(递归):
void FindMin(int a[], int b[], int n, int &sum)
{
int i;
int j;
int x=0,n1,n2;
bool flag=false;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
{
int tmp=a[i]-b[j];
if ((sum>0 && tmp>0 && tmp<sum)||(sum<0 && tmp<0 && tmp>sum))
{
if(abs(tmp-sum/2)>abs(x-sum/2))
{
x=tmp;
n1=i;
n2=j;
flag=true;
}
}
}
if (flag)
{
sum-=2*x;
a[n1]^=b[n2];
b[n2]^=a[n1];
a[n1]^=b[n2];
FindMin(a,b,n,sum);
}
}
void main()
{
int a[3]={198,1,1};
int b[3]={90,90,30};
int sum=0;
for (int i=0;i<3;i++)
{
sum+=a[i]-b[i];
}
FindMin(a,b,3,sum);
cout<<abs(sum)<<endl;
}
- 一个公司面试题~!
- 一个数据库面试题
- 一个面试题
- 一个面试题
- 一个sql面试题
- 一个SQL面试题
- 一个面试题
- 一个面试题
- 一个SQL面试题
- 一个小面试题
- 一个面试题
- 腾讯面一个试题
- 一个面试题
- 一个fork 面试题
- 一个数组面试题
- 一个Java面试题
- 一个面试题。。。
- 一个php面试题
- 转:宇文泰苏卓对答录
- sql数据库连接
- oracle database link使用
- php复制文件夹以及文件夹里的所有文件
- 【转载】SQL连接查询
- 一个面试题
- 21条SQL Server数据库开发经验
- My Eclipse 优化配置
- 创建任何自定义形状的控件
- JAVA WEB应用下监听与定时器的配合使用
- 测试用例的初步介绍
- 详细介绍微软SQL Server 2008
- 用VC进行COM编程所必须掌握的理论知识
- ADO连接数据库