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

来源:互联网 发布:淘宝智能旺铺多少钱 编辑:程序博客网 时间:2024/05/18 03:35

原题:有一序列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,l2print ('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-=1if sum1>=sum2:    cha = sum1-sum2else:    cha = sum2-sum1print lis3print lis4print sum1print sum2print 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 - 1    tflag = 1    global flag    global cha    while 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 = 0                break        else:            r -= 1    if (r < 0):        flag = 0    return (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) / 2    llist = sourcelist[:lenth]    rlist = sourcelist[lenth:]    cha = sum(rlist) - sum(llist)    flag = 1    while flag:        (llist, rlist) = change(llist, rlist)    print llist, sum(llist)    print rlist, sum(rlist)    print cha





阅读全文
0 0
原创粉丝点击