有兩個序列a,b,大小都為n,序列元素的值任意整數,無序;要求:通過交換a,b中的元素,使[序列a元素的和
阿新 • • 發佈:2019-01-05
原題:有一序列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) - 1 while 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-sum1 print 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)/2
sourcelist.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