AcWing 843. n-皇后問題(DFS回溯)
阿新 • • 發佈:2021-02-01
n-皇后問題是指將 n 個皇后放在 n∗n 的國際象棋棋盤上,使得皇后不能相互攻擊到,即任意兩個皇后都不能處於同一行、同一列或同一斜線上。
現在給定整數n,請你輸出所有的滿足條件的棋子擺法。
輸入格式
共一行,包含整數n。
輸出格式
每個解決方案佔n行,每行輸出一個長度為n的字串,用來表示完整的棋盤狀態。
其中”.”表示某一個位置的方格狀態為空,”Q”表示某一個位置的方格上擺著皇后。
每個方案輸出完成後,輸出一個空行。
輸出方案的順序任意,只要不重複且沒有遺漏即可。
資料範圍
1≤n≤9
輸入樣例:
4
輸出樣例:
.Q..
. ..Q
Q...
..Q.
..Q.
Q...
...Q
.Q..
思路:
深度優先遍歷dfs。
每一行必定有一個皇后,對行進行深度遍歷
對於第 r 行的第 i 個位置, ,判斷每個點是否可以放皇后,如果可以,則放皇后,然後處理 r + 1 行。
直到 r = n,程式指行完畢。
答案:
#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define INF 0x3f3f3f3f
const int N = 2e5 + 10;
const int M = 15;
using namespace std;
int n;
char dp[M][M];
bool vis_r[2*M]; ///右斜對角線標記
bool vis_l[2*M]; ///左斜對角線標記
bool vis[M]; ///列標記
int dis[M];
int ans;
void DFS(int pos){
if(pos>=n){ ///遞迴終止條件:放慢棋盤
//ans++; ///答案+1
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<dp[i][j];
}
cout<<endl;
}
cout<<endl;
return ;
}
for(int i=0;i<n;i++){
///若對應的列、左斜對角線、右斜對角線無棋子,可以放置
if(!vis[i]&&!vis_l[i+pos]&&!vis_r[n-i+pos]){
dp[pos][i]='Q';
vis[i]=vis_l[i+pos]=vis_r[n-i+pos]=1; ///標記走過
DFS(pos+1); ///DFS下一行
vis[i]=vis_l[i+pos]=vis_r[n-i+pos]=0; ///回溯
dp[pos][i]='.';
}
}
}
void init(){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
dp[i][j]='.';
}
}
}
int main(){
cin>>n;
init();
DFS(0);
// cout<<ans<<endl;
return 0;
}