DFS與N皇后問題

2022-10-07 01:33:07 字數 1850 閱讀 8665

dfs是指深度優先遍歷也叫深度優先搜尋

它是一種用來遍歷或搜尋樹和圖資料結構的演算法

注:關於樹的一些知識可以去看《樹的概念及基本術語》這篇文章

它會不斷地沿著節點的深度方向(該深度方向為其鄰接點的方向)進行遍歷

dfs主要步驟有以下幾步

空間複雜度

dfs演算法實際上是乙個遞迴演算法,需要借助乙個遞迴工作棧

故時間複雜度

為什麼不確定?

因為遍歷圖的過程實質上是對每個頂點找查其所有鄰接點的過程,其耗費時間取決於所採用結構

下面給出常用的幾種資料結構dfs時的時間複雜度

(注:n是圖中結點的個數,e是圖中邊的個數。)

hdu 2553 n皇后問題

在n*n的方格棋盤放置了n個皇后,使得它們不相互攻擊(即任意2個皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。

你的任務是,對於給定的n,求出有多少種合法的放置方法。

輸入:共有若干行,每行乙個正整數n≤10,表示棋盤和皇后的數量;如果n=0,表示結束。

輸出:共有若干行,每行乙個正整數,表示對應輸入行的皇后的不同放置數量。

輸入樣例:18

50輸出樣例:192

10

而經典的dfs,基本是將所有子節點全部擴充套件開,再選取最新的節點進行擴充套件。

但是對於n皇后來說,我們如果一一枚舉,則有n的n次方種情況.

即使n=10,則有10^10種情況,我們還要在這些情況中進行篩選,這無疑需要巨大的計算

故:我們需要對dfs進行優化

我們可以讓程式在某節點由某些條件就可以判斷再進行繼續展開並不符合要求,然後立即返回,達到回溯和減少樹的枝幹的生成(減枝)的目的,從而進行優化。

下面給出n=4時減枝的樹狀**

關鍵問題

關鍵問題:在擴充套件節點時如何去掉不符合條件的節點?

設左上角是(0,0),已經放好皇后是(i,j),不同行、列、斜線的新皇后是(r,c),則:

其他問題

#include using namespace std;

//tot記錄每次n取特定值能放置n皇后情況的個數,每當n改變時tot重置為0

int n, tot = 0;

//表示皇后存放位置 col[r] = c 表示第r行的皇后在第c列

int col[10];

//r為行,c為列

//check()用於檢查新放置的皇后(r,c)是否和已經存放好的皇后衝突

//衝突返回false,不衝突返回true

bool check(int r, int c)

//r為檢索的行

//對每行檢索並放置皇后

void dfs(int r)

//對第r行(層)的每一列進行檢索,若能放置則進入下一行(層)再從r+1行第0列向後檢索放置依次類推

//若不能放置則本層次結束,遞迴然後回溯出去再改變上一層的列數,從該列再進行展開

for(int c=0;c> n)

return 0;

}

下面給出n從1到10取值的資料以供參考

n取1的結果為:1

n取2的結果為:0

n取3的結果為:0

n取4的結果為:2

n取5的結果為:10

n取6的結果為:4

n取7的結果為:40

n取8的結果為:92

n取9的結果為:352

n取10的結果為:724

以下對於本題解法而言

對於n>11且n<=15可用資料結構舞蹈鏈較快解決

N皇后問題 DFS

在n n的方格棋盤放置了n個皇后,使得它們不相互攻擊 即任意2個皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。你的任務是,對於給定的n,求出有多少種合法的放置方法。input 共有若干行,每行乙個正整數n 10,表示棋盤和皇后的數量 如果n 0,表示結束。output 共有若...

N皇后問題 dfs)

在n n的方格棋盤放置了n個皇后,使得它們不相互攻擊 即任意2個皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。你的任務是,對於給定的n,求出有多少種合法的放置方法。input 共有若干行,每行乙個正整數n 10,表示棋盤和皇后的數量 如果n 0,表示結束。output 共有若...

N皇后問題 DFS

題 在n n的方格棋盤放置了n個皇后,使得它們不相互攻擊 即任意2個皇后不允許處在同一排,同一列,也不允許處在與棋盤邊框成45角的斜線上。你的任務是,對於給定的n,求出有多少種合法的放置方法。input 共有若干行,每行乙個正整數n 10,表示棋盤和皇后的數量 如果n 0,表示結束。output 共...