題目連線
經過思考,不難發現:恰好n個皇后放在不同行不同列,那麼是不是可以轉換成n個皇后所在行分別確定(一人一行)的情況下對她們的所在列的列舉。
也就是列的全排列生成問題,我們用c[x]表示x行皇后的列編號。而我們知道0~n-1的排列一共有n的階乘,列舉量不會超過它。
if(cur==n)//遞迴邊界。只要走到這裡,所有的皇后必然不衝突
tot++;
根據我們的**,我們是從cur=0開始的,
1 #include2 #include3using
namespace
std;
4int n,tot,c[1000];5
void search(int
cur)620
if(ok)
21 search(cur+1);//
如果合法,繼續遞迴22}
23}24int
main()
2533
while(cin>>n&&n)
3437 }
search(cur+1);//如果合法,繼續遞迴 並不會判斷n+1行的皇后。所以我們從cur=0開始。
當然從cur=1開始也是可以的,但此時
if(cur==n+1)//遞迴邊界。只要走到這裡,所有的皇后必然不衝突
tot++;
程式中的
if(c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])//檢查是否與前面的皇后衝突
既然是逐行放置,那麼皇后肯定不會橫向攻擊,因此只需檢查是否縱向和斜向攻擊即可。條件c[cur]==c[j]||cur-c[cur]==j-c[j]||cur+c[cur]==j+c[j])
y-x標示了主對角線,斜率為1;
y+x標示了副對角線,斜率為-1;
畫畫圖就知道了
我們還可以用二維陣列vis[2]直接判斷當前嘗試放的皇后的對角線和縱向有沒有皇后已經放了,注意主對角線標示y-x可能為負數,所以要加n
1 #include2 #include3 #include4 #include5using
namespace
std;
6int n,tot,c[1000];7
int vis[3][1000];8
void search(int
cur)919
}20}21
}22intmain()
2332
while(cin>>n&&n)
3336 }
006回溯法 n皇后問題
在n n格的棋盤上放置彼此不受攻擊的n個皇后。按照西洋棋的規則,皇后可以攻擊與之處在同一行或同一列或同一斜線上的棋子。n後問題等價於在n n格的棋盤上放置n個皇后,任何2個皇后不放在同一行或同一列或同一斜線上。如下 nqueen by xcz on 2013.9.10 include include...
N皇后問題 12 回溯法 簡單
回溯法,主要應用在dfs中,主要思想是當你push乙個元素後,記住要pop回去,大致的模板是 path.push back nums i dfs pos 1 path.pop 詳細的模板在我們之前用回溯法解決全排列問題有提到。n 皇后問題研究的是如何將 n 個皇后放置在 n n 的棋盤上,並且使皇后...
1 25回溯 n皇后問題,素數環,困難的串
回溯 當把問題分成若干個步驟時,如果當前部驟沒有合法選擇,則函式將返回上一級遞迴呼叫,這種現象稱為回溯,因此,遞迴列舉演算法有常被稱為回溯法 n皇后問題 思考 1。從64個格仔選出乙個子集使得任意乙個格仔不在同一行同一列同一對角線上,即子集列舉問題,64個格仔的子集有2 64個,太大不夠好 2。從6...