- 解法一:这种解法和排列数字的解法类似,自我感觉这种解法比第二种解法要好理解
#include<iostream>
using namespace std;
const int N=20;
int n;
char g[N][N];
int l[N],ug[N],ng[N];
void dfs(int u){
if(u==n){
for(int i=0;i<n;i++){
cout<<g[i]<<endl;
}
cout<<endl;
return ;
}
for(int i=0;i<n;i++){
if(!l[i]&&!ug[i+u]&&!ng[i-u+n]){
g[u][i]='Q';
l[i]=ug[i+u]=ng[i-u+n]=1;
dfs(u+1);
l[i]=ug[i+u]=ng[i-u+n]=0;
g[u][i]='.';
}
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
g[i][j]='.';
}
}
dfs(0);
return 0;
}
*
- 解法二:对于该种解法需要注意几个问题:
- 1.开头的两个if语句不能互换位置,否则不能ac ,呜呜,但是这个回溯啥的太复杂了,我还不明白为什么:
- 现在知道了,如果互换位置,在进入下边if判断语句进行剪枝时,会出现i=n,还会出现j=n的情况出现
- 数组越界的情况,所以如果要是互换位置在下边语句中加入i<n,j<n,就可以了
-
2.dfs(i,j+1,c);这个语句前边不能加上Else,在一次循环中该语句必执行
-
解法一和解法二的异同点:解法一一个皇后就在一行,所以只需要找列,比较简单,
- 解法二一个一个的空格进行筛选,如果符合进入dfs(i,j+1,c+1),但是不能保证这之后的
- 所有皇后都能满足要求,所以回溯后可能会进入dfs(i,j+1,c)。
#include<iostream>
using namespace std;
int n;
const int N=20;
char g[N][N];
int row[N],l[N],ug[N],ng[N];
void dfs(int i,int j,int c){
if(j==n){
j=0;
i++;
}
if(i==n){
if(c==n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<g[i][j];
}
cout<<endl;
}
cout<<endl;
}
return ;
}
if(!row[i]&&!l[j]&&!ug[i+j]&&!ng[j-i+n]){ //&&i<n&&j<n
g[i][j]='Q';
row[i]=l[j]=ug[i+j]=ng[j-i+n]=1;
dfs(i,j+1,c+1);
row[i]=l[j]=ug[i+j]=ng[j-i+n]=0;
g[i][j]='.';
}
dfs(i,j+1,c);
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
g[i][j]='.';
}
}
dfs(0,0,0);
return 0;
}