n皇后 位運算版

2021-05-25 23:39:35 字數 2242 閱讀 6275

n皇后問題是大家在遞迴裡會碰到的乙個經典問題。以前高中我學dfs的時候,老師首先讓我看的就是八皇后。

不過這皇后的時間複雜度大家可想而知了。而接下來的位運算將這個效率重新提到乙個高度。

我是以前在matrix67大牛那裡學的,最近資料結構實驗剛好碰到n皇后,就在這裡「複述」一遍吧。

code:

void

doans(

intr, 

intld, 

intrd)  

}  else

sum++;  

}  

乍一看有點模糊吧?沒錯,這就是n皇后的遞迴函式了。我們乙個個來解析。

首先uplimit是(1 << n) - 1,如果n是8的話uplimit就是255,看做二進位制就是11111111。聰明的人一看就知道了,這裡每一位就代表乙個皇后。

而r代表每一列能放與否,如10001110就代表第2、3、4、8個能放。

所以開始乙個if來判斷皇后放齊了沒。如果齊了,顯然r也要等於11111111。

還有ld和rd分別是對角線的各位能放與否。

我們來看看下圖(from matrix67):

假設我們已經遞迴到第三行了(左圖),這裡可以看出r為101010也就是說

二、四、六可以放。ld是100100(藍色線),二、三、五、六可以放,rd為000111,。

好的,那麼哪幾個可以放呢?我們將r、ld、rd或運算一遍(或者r有或者ld有或者rd有),得到101111,也就是說這三個合起來的話就只能放第二格了。然後我非運算一遍,得到的是010000,非運算之後1代表可以放,0代表不可以放了。然後我們再與運算一遍就得到可以放的位置了:010000。

code:

intp = pos & (~pos + 1);  

這一句我們可以用

code:

intp = pos & -pos;  

來代替,什麼意思呢?其結果是取出最右邊的那個1。比如我們有乙個數字pos是10010,那麼p得到的結果就是10了。那麼上面那個010000得到的結果就是10000了。然後我們更新一遍pos:讓它減去p也就是10000,那麼pos得到的結果就是000000。也就是說下一次迴圈就跳出了。

看看傳進去的三個引數:

r + p為下一層遞迴的r,即10000 + 101010 = 111010那就相當於放進第二個了。

(ld + p) << 1為下一層的ld,即(100100 + 10000) << 1為(110100) << 1也就是1101000了。當然,在下一層遞迴的時候第乙個1將會被uplimit & ~(r | ld | rd)截掉成為101000。

(rd + p) >> 1為下一層的rd,即(000111 + 10000) >> 1為(010111) >> 1也就是001011。

那麼在新的一層裡又有新的r和ld還有rd組合了。

主題的思路就是這樣子的。

code:

/*** @brief n皇后問題 - 位運算版

* @author 朱凱迪

* 2010/11/22

*/#include 

#include 

using

namespace

std;  

/** 方案鍊錶 */

list

> sol;  

/** 棋盤大小 */

intn;  

/** 棋盤擺滿時的數字 */

intuplimit;  

void

print()  

for(int

j = 0; j 

"■");  

printf("○"

);  

for(

intj = cnt + 1; j 

"■");  

printf("/n"

);  

}  printf("/n"

);  

}  void

doans(

intr, 

intld, 

intrd)  

}  else

print();  

}  int

main()  

return

0;  

}  

位運算解決N 皇后問題

描述 位運算是定義在整數上的運算。但在做位運算的時候,並不把整數看作整數,而是將它們看做一系列二進位制數字,逐位進行運算。位運算有6種,他們的名稱,運算子及運算規則如下 與 and 5 6 4 101 110 100 或 or 5 6 7 101 110 111 異或 xor 5 6 3 101 1...

位運算n皇后 洛谷1219

老鐵已經很久沒有更博了。自從考完noip後老鐵一蹶不振,從此走上心理陰影無限大,吾將上下而求索的道路。又去石家莊聽課 並不能聽懂 於是自己學一學一些奇怪的演算法。題目描述 檢查乙個如下的6 x 6的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行 每列有且只有乙個,每條對角線 包括兩條主對角線的所有平行...

演算法 位運算 與 n皇后問題

問題a 返回n皇后擺法有多少種?遞迴函式,維護三個變數和乙個常量 常量 upperlim 代表棋盤大小,末尾n個1,例如八皇后,00 011111111 變數 顯然,遞迴函式的跳出條件為,nowlim upperlim 其中每層遞迴函式,可以通過位運算快速找到可以擺放的位置。pos upperlim...