2016-07-31 83 views
2

我一直在試圖弄清楚如何處理這個問題,有人可以給我一個算法或一組步驟來解決這個問題的想法嗎?我真的很難過。代碼是沒有必要的。我打算解決它Python3,C和Rust。算法按位變換滿足方程

考慮四個數字:a,b,c和k。您必須在a和b中至多更改k個位,以形成滿足方程a'|的數字a'和b' b'= c。 |表示按位或運算。

如果不存在這樣的值,則返回-1。在多種解決方案的情況下,儘可能小;如果仍然有多種解決方案,儘可能使b'儘可能小。如果在a中改變的比特數是k.a(對於b類似地k.b),則k.a + k.b < = k。

回答

2

我假設所需的結果是異或掩模,即。與1,其中位應該被改變和0的數字,其中他們應該被保持不變(使得a XOR amask = a'b XOR bmask = b'

只是爲了完整性,的a' | b'結果有1個比特,其中任一個「或b」或兩者都具有1,否則爲0.

首先,絕對必要的條件是a' | b' = c是a'和b'都沒有1位,其中c有0位。換句話說,要獲得第一個amask和bmask,可以將a和b設置爲0,其中c爲1。換句話說,要獲得第一個amask和bmask,可以採用a和b並設置每一個位爲0,其中c的二進制補碼爲0。

amask = a & (~c) 
bmask = b & (~c) 

現在指望有多少位AMASK和bmask爲1(或用幼稚的循環,或與許多popcount功能之一在線),和從你的k中減去它。如果k變負,則不存在解決方案(返回-1)。

第二部分要求您找到a和b均爲0但c爲1的位。把它簡稱:
temp_mask = c & ((a XOR amask) | (b XOR bmask))
temp_mask是你需要設置爲1 要麼位a或b(哪一個取決於「最小」的要求,但第一,流行數temp_mask也一樣,如果結果。比你的剩餘k大,有沒有辦法解決(返回-1)

下一步很簡單:
amask = amask | temp_mask
此前曾AMASK 1,其中c爲0,這種說法現在不會重疊任何東西。

現在,您至少有一個解決方案a' | b' = c,即
(a XOR amask) | (b XOR bmask) = c
但是仍然可能有另一個較小的a,對吧?

這也不是很難:在(a XOR amask)中爲1的每個位,而在(b XOR bmask)中的0都可以「移動」,即。使其在(a XOR amask)中爲0,在(b XOR bmask)中爲1。結果c將是相同的,但數字值(a XOR amask)將會更小(可能最壞的情況下它保持不變)。

temp_mask = (a XOR amask) & (~(b XOR bmask)) 
amask = amask XOR temp_mask 
bmask = bmask XOR temp_mask 

爲了實現這一點,請注意unsigned和int大小。

全部僞代碼:

amask = a & (~c) 
bmask = b & (~c) 
temp_mask = c & ((a XOR amask) | (b XOR bmask)) 
amask = amask | temp_mask 
temp_mask = (a XOR amask) & (~(b XOR bmask)) 
amask = amask XOR temp_mask 
bmask = bmask XOR temp_mask 
1

較慢的方式:

  • 迭代所有位。
  • 如果在a或b中設置了一位而在c中沒有設置位,則將其重置爲'和b'(計數:1或2)。
  • 如果在c中設置了它,但a和b都缺少,則將其設置爲b'(count:1)。

讓它快速使用這樣的信息:

  • 在查找額外的比特:一個&〜C(需要在任何情況下被刪除)

  • 查找b中的額外比特: b &〜C(需要在任何情況下被刪除)

  • 尋找失蹤位:〜(A | b)& C(需在b被設置 '保持' 小)

如果相應的位計數的總和爲< = k,則可行。