地址:
https://www.acwing.com/problem/content/845/
https://leetcode-cn.com/problems/n-queens/
描述:
思路:
整体的思路:我们要枚举每一行的皇后应该放在第几列上
其实和全排列的思想非常类似
代码:
回溯(剪枝)思路:
#include <iostream>
using namespace std;
int n;
//1<=n<=9
const int N=10;
char qi[N][N];
//分别记录的是该位置的列,正对角线,斜对角线上是否放过皇后,若均没有皇后,填入皇后,并递归到下一行
//为什么正对角和反对角要2*N,因为列只有N条,而对角线有2*N条
bool lie[N],z[2*N],f[2*N];
//当前枚举的是第x行的Q应该放在第y列?
void dfs(int x){
//此时Q已经全部放完
if(x==n){
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
cout << qi[i][j];
cout << endl;
}
cout << endl;
return;
}
//y表示第y列
for(int y=0;y<n;y++){
//x-y+n和x+y怎么得来的见图解
if(!lie[y]&&!z[x-y+n]&&!f[x+y]){
lie[y]=z[x-y+n]=f[x+y]=true;
//要是它的同一条列,正对角和反对角都没有皇后,那么就在第x行第y列放上皇后
qi[x][y]='Q';
//递归去求下一行
dfs(x+1);
//回溯
lie[y]=z[x-y+n]=f[x+y]=false;
qi[x][y]='.';
}
}
}
int main(){
cin>>n;
//初始化棋盘
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
qi[i][j]='.';
}
}
dfs(0);
return 0;
}
Leetcode
class Solution {
public:
int n;
vector<bool> lie,z,f;
vector<vector<string>> ans;
vector <string> temp;
vector<vector<string>> solveNQueens(int _n) {
n=_n;
lie=vector<bool>(n);
z=f=vector<bool>(2*n);
temp=vector<string> (n,string(n,'.'));
dfs(0);
return ans;
}
void dfs(int x){
if(x==n){
ans.push_back(temp);
return ;
}
for(int y=0;y<n;y++){
if(!lie[y]&&!z[x+y]&&!f[x-y+n]){
lie[y]=z[x+y]=f[x-y+n]=true;
temp[x][y]='Q';
dfs(x+1);
temp[x][y]='.';
lie[y]=z[x+y]=f[x-y+n]=false;
}
}
}
};
一个个遍历
#include <iostream>
using namespace std;
int n;
//1<=n<=9
const int N=10;
char qi[N][N];
//分别记录的是该位置的行,列,正对角线,斜对角线上是否放过皇后,若均没有皇后,填入皇后,并递归到下一行
//为什么正对角和反对角要2*N,因为列只有N条,而对角线有2*N条
bool hang[N],lie[N],z[2*N],f[2*N];
//整体思路:一个一个看是否要放皇后
//num记录已经放下的皇后数量
void dfs(int x,int y,int num){
//这一行的皇后放完了
if(y==n) {
//转到下一行,开始遍历
y=0;
x++;
}
if(x==n){
if(num==n){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cout<<qi[i][j];
}//for(j)
cout<<endl;
}//for(i)
cout<<endl;
}
return ;
}
//不放皇后
dfs(x,y+1,num);
//放皇后
if(!hang[x]&&!lie[y]&&!z[x-y+n]&&!f[x+y]){
hang[x]=lie[y]=z[x-y+n]=f[x+y]=true;
qi[x][y]='Q';
//写成dfs(x+1,0,nums+1)也可以
dfs(x,y+1,num+1);
hang[x]=lie[y]=z[x-y+n]=f[x+y]=false;
qi[x][y]='.';
}
}
int main(){
cin>>n;
//初始化棋盘
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
qi[i][j]='.';
}
}
dfs(0,0,0);
return 0;
}