有乙個n*n的棋盤,有些格仔可以放置皇后,乙個皇后可以對它這一行的位置,這一列的位置,它所在的左對角線和右對角線攻擊,這些位置不能放置皇后,一共放置n個皇后,問有多少種放置的方式。
輸入格式:
第一行有乙個n。接下來有n行n列描述乙個棋盤,「*」表示可放「.」表示不可放。
輸出格式:
輸出方案總數
這道題主要考察位運算,例如101001表示這一排第2、4、5個位置可以放置皇后。
我們用k進製(這裡是二進位制)來儲存狀態,這也是狀態壓縮的基本思想。
顯然每行只能放置乙個皇后,我們逐行列舉
那麼我們需要記錄四個狀態,一是這一行題目給定的狀態,二是這一行中有哪些列會被之前擺放的皇后攻擊,那麼無法再擺放,三是左對角線的影響,四是右對角線的影響,這些狀態只用每行乙個數字的二進位制來儲存就行了。
判斷時將這四種情況取並集,再取反,1的位置就成了可以放置的位置,利用lowbit進行dfs即可,具體的實現細節還要看**
#include#include#include
#define re register
using
namespace
std;
int n,all,sta[50
],ans;
string
s;int lowbit(int x)//
找到最右邊的1位 //
取反是補碼,與反碼不同 ~(3)=-4;
void dfs(int now,int l,int r,intd)
//當now==all的時候,說明全部擺放完畢,ans++
//now表示到這一行的擺放情況,l表示左對角線的情況
//r表示右對角線的情況,d記錄現在在哪一行,
//sta[d]表示第d行題目的限制條件
int pos=all&(~(now|l|r|sta[d])),p; //
all是用來限制,把右對角線左移移出去的除掉
while(pos)//
列舉每個可以放的位置
}int
main()
dfs(
0,0,0,1);//
一開始沒放,沒有任何擺放過皇后限制
printf("%d"
,ans);
return0;
}
位運算解決N 皇后問題
描述 位運算是定義在整數上的運算。但在做位運算的時候,並不把整數看作整數,而是將它們看做一系列二進位制數字,逐位進行運算。位運算有6種,他們的名稱,運算子及運算規則如下 與 and 5 6 4 101 110 100 或 or 5 6 7 101 110 111 異或 xor 5 6 3 101 1...
演算法 位運算 與 n皇后問題
問題a 返回n皇后擺法有多少種?遞迴函式,維護三個變數和乙個常量 常量 upperlim 代表棋盤大小,末尾n個1,例如八皇后,00 011111111 變數 顯然,遞迴函式的跳出條件為,nowlim upperlim 其中每層遞迴函式,可以通過位運算快速找到可以擺放的位置。pos upperlim...
n皇后 位運算版
n皇后問題是大家在遞迴裡會碰到的乙個經典問題。以前高中我學dfs的時候,老師首先讓我看的就是八皇后。不過這皇后的時間複雜度大家可想而知了。而接下來的位運算將這個效率重新提到乙個高度。我是以前在matrix67大牛那裡學的,最近資料結構實驗剛好碰到n皇后,就在這裡 複述 一遍吧。code void d...