原题:有一序列a,大小为n,分为2部分,序列元素的值任意整形数,无序;
要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小,用python写。
#coding=utf-8
# 1.将两序列合并为一个序列,并排序,为序列Source
# 2.拿出最大元素Big,次大的元素Small
# 3.在余下的序列S[:-2]进行平分,得到序列max,min
# 4.将Small加到max序列,将Big加大min序列,重新计算新序列和,和大的为max,小的为min。
# Python代码
def mean(sorted_list):if not sorted_list:return(([],[]))big=sorted_list[-1]small=sorted_list[-2]big_list,small_list=mean(sorted_list[:-2])big_list.append(small)small_list.append(big)big_list_sum=sum(big_list)small_list_sum=sum(small_list)if big_list_sum>small_list_sum:return((big_list,small_list))else:return((small_list,big_list))
li=[5,5,9,9,1]
l =[4,7,7,8,5]
l.extend(li)
l.sort()
l1,l2=mean(l)
print l1,l2
print ('Distance:%s'%abs(sum(l1)-sum(l2)))
print ('-*'*40)
# 输出结果
# [4, 5, 5, 7, 9] [1, 5, 7, 8, 9]
# Distance:0
解题思路一:
1.列表合并排序,设两个空列表
2.最大值添加第一个列表
3.比较两个列表差,循环放入最小列表中
代码如下(Python2.7.5):
list1=[1,21,3,14]
list2=[8,4,5,7]
li=[]
lis3 = []
lis4 = []for i in list1:li.append(i)
for i in list2:li.append(i)li.sort()
sum1=sum(lis3)
sum2=sum(lis4)
i = len(li) - 1while i >= 0 :if sum1>=sum2:lis4.append(li[i])sum2=sum(lis4)else:lis3.append(li[i])sum1=sum(lis3)i-=1
if sum1>=sum2:cha = sum1-sum2
else:cha = sum2-sum1print lis3
print lis4
print sum1
print sum2
print cha
解题思路二:
假如最小数是负数,这样题目就很简单,代码如下:
li1=[1,21,3,14]
li2=[8,4,5,7]sourcelist=[]for i in li1:sourcelist.append(i)
for j in li2:sourcelist.append(j)
sourcelist.sort()size=len(sourcelist)/2sourcelist.sort()print sum(sourcelist[:size])-sum(sourcelist[size:])
假如最小值为正数,当前数组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'|= |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为止。
def change(llist, rlist):r = lenth - 1tflag = 1global flagglobal chawhile r >= 0 and tflag:for l in range(lenth):if ((rlist[r] - llist[l]) * 2 <= cha and rlist[r] > llist[l]):rlist[r], llist[l] = llist[l], rlist[r]rlist.sort()llist.sort()cha = sum(rlist) - sum(llist)tflag = 0breakelse:r -= 1if (r < 0):flag = 0return (llist, rlist)if (__name__ == '__main__'):li1=[1,21,3,14]li2=[8,4,5,7]sourcelist=[]for i in li1:sourcelist.append(i)for j in li2:sourcelist.append(j)sourcelist.sort()lenth = len(sourcelist) / 2llist = sourcelist[:lenth]rlist = sourcelist[lenth:]cha = sum(rlist) - sum(llist)flag = 1while flag:(llist, rlist) = change(llist, rlist)print llist, sum(llist)print rlist, sum(rlist)print cha