我正在研究Snapper Chain問題,並在這裏尋找關於如何在解決方案中遇到的位旋轉算法的解釋。我發現了一些很好的信息,但是我仍然花了很長時間才弄明白自己是一個點點滴滴。
這裏是我嘗試解釋算法以及如何提出它。如果我們列舉鏈中每個笛卡爾所有可能的電源和ON/OFF狀態,我們會看到一個模式。給出的測試情況下,N = 3,K = 7(3種笛鯛,7扣)中,我們顯示每個鯛的功率和ON/OFF狀態,每第k個單元:
1 2 3
0b:1 1 1.1 1.0 0.0 -> ON for n=1
0b:10 2 1.0 0.1 0.0
0b:11 3 1.1 1.1 1.0 -> ON for n=1, n=2
0b:100 4 1.0 0.0 1.0
0b:101 5 1.1 1.0 1.0 -> ON for n=1
0b:110 6 1.0 0.1 0.1
0b:111 7 1.1 1.1 1.1 -> ON for n=2, n=3
的燈泡是在當所有笛鯛打開並接收電源,或者當我們有第k個快照導致n 1s時。更簡單地說,當所有笛卡爾接通時燈泡都點亮,因爲它們都必須接通電源才能接通(因此燈泡)。這意味着每k次拍攝,我們需要n 1s。另外,你可以注意到k不僅滿足n = 3的k = 7,而且滿足n = 2且滿足n = 2的k = 1的k = 3。此外,對於n = 1或2,我們可以看到每打開一個燈泡的數量,k的最後n個數字總是1.我們可以試圖概括出所有滿足n個笛卡爾的k將是一個以1.
n個數字,我們可以使用較早的海報提到的表達比1 < < N - 1總是給我們n個1的二進制數字,或在這種情況下,1 < < 3 - 1 = 0b111。如果我們把我們的n個笛卡爾鏈看作一個二進制數,其中每個數字表示開/關,並且我們需要n個數字中的一個,這就給了我們表示。
現在,我們希望找到那些情況下,1 < < N - 1等於某個k,在1個二進制數字,這是我們通過執行按位並做結尾:克&(1 < < N - 1)得到k的最後n位數,然後將其與1 < < n - 1相比較。
我想這種類型的思維在處理這些類型的問題之後會變得更加自然,但它仍然很嚇人對我而言,我懷疑自己會想出一個這樣的解決方案!
這裏是我的解決方案在Perl:
$tests = <>;
for (1..$tests) {
($n, $k) = split//, <>;
$m = 1 << $n - 1;
printf "Case #%d: %s\n", $_, (($k & $m) == $m) ? 'ON' : 'OFF';
}
幫你聯繫,召回'10000 - 1 = 9999',大致同樣的事情發生在二進制 – Anycorn 2010-05-09 15:56:37
@aaa的確!現在它更有意義。 – srandpersonia 2010-05-09 16:13:24
我更喜歡(k ^(k + 1))>> n – 2012-06-28 23:34:07