混合顏料-網易python(求矩陣的秩)
阿新 • • 發佈:2019-01-27
題目描述
你就是一個畫家!你現在想繪製一幅畫,但是你現在沒有足夠顏色的顏料。為了讓問題簡單,我們用正整數表示不同顏色的顏料。你知道這幅畫需要的n種顏色的顏料,你現在可以去商店購買一些顏料,但是商店不能保證能供應所有顏色的顏料,所以你需要自己混合一些顏料。混合兩種不一樣的顏色A和顏色B顏料可以產生(A XOR B)這種顏色的顏料(新產生的顏料也可以用作繼續混合產生新的顏色,XOR表示異或操作)。本著勤儉節約的精神,你想購買更少的顏料就滿足要求,所以兼職程式設計師的你需要程式設計來計算出最少需要購買幾種顏色的顏料?
輸入描述:
第一行為繪製這幅畫需要的顏色種數n (1 ≤ n ≤ 50)
第二行為n個數xi(1 ≤ xi ≤ 1,000,000,000),表示需要的各種顏料.
輸出描述:
輸出最少需要在商店購買的顏料顏色種數,注意可能購買的顏色不一定會使用在畫中,只是為了產生新的顏色。
示例1
輸入
3
1 7 3
輸出
3
解析:
# 混合顏料 相當於求矩陣的秩
# 參考第一個解答: https://www.nowcoder.com/questionTerminal/5b1116081ee549f882970eca84b4785a
#
# 題意表示,通過最小的一組顏料,來表達所需的顏料;類似於,通過平面一組向量[0,1],[1,0]來表示整個平面類似
# 原理:一個公式:A^B = C 推出:B^C=A、A^C=B
# 將數字轉化為二進位制,通過01矩陣的秩,即為所求。這個過程類似於求解齊次方程組中的唯一解(參考線性代數)
# 例子:colors 1 5 7,轉為二進位制陣列 [[111][101][001]](其他的需要排序)
# 比較最大的兩個數111和101的最高位,相同則進行相減,得010(2),新增2到陣列colors中,同時刪除最大的數111(7)
# 如果不同,表示最高位為一個基(即一種必須的顏料,num+1)
# 直到最後colors中只有兩個數字,這兩個數字必須由這兩個數字組合
# 計算數字的二進位制位數,用於判斷數字位數是否相同(111與101相同)
def getHighPosition(number):
count = 0
while number > 0:
number = number>>1
count += 1
return count
n = int(input())
colors = list(map(int,input().split()))
colors.sort()
# 分別記錄最後兩個數的下標(最大的兩個數)
lastIndex = len(colors)-1
bLastIndex = lastIndex-1
num = 0
while len(colors) > 2:
if getHighPosition(colors[lastIndex]) == getHighPosition(colors[bLastIndex]):
temp = colors[lastIndex]^colors[bLastIndex]
if not colors.__contains__(temp):
colors.append(temp) # 需要使用append而不是add
colors.sort()
lastIndex += 1
bLastIndex += 1
else:
num += 1
colors.pop()
lastIndex -= 1
bLastIndex -= 1
print(num+len(colors))