位運算的魅力 N皇后問題

2022-05-05 16:39:21 字數 1156 閱讀 1944

有乙個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...