DFS 看 搜索顺序
递归步骤:1.边界 2.递归 3.恢复现场
第一种搜索方式(按行搜索)
/*
第一种搜索顺序
定义纵坐标为y轴,横坐标为x轴,u是每一层的状态,i是枚举每一列的状态,那么y:u, x:i;
正对角线y = x+b -> b = y-x+n; 反对角线是 y = -x+b -> b = x+y;那么应该是dg[n+u-i],udg[u+i].
*/
#include <iostream>
using namespace std;
const int N = 20; // 对角线的数量是n*2,所以要开20
int n;
char g[N][N];
bool col[N],row[N],dg[N],udg[N];//col是行,row是列,dg是正对角线,udg是反对角线
void dfs(int u)
{
// 1.边界 2.递归 3.恢复现场
if(u == n)
{
for(int i = 0; i < n; i++) cout << g[i] << endl;
cout << endl;
return ;
}
// y:u, x:i
for(int i=0;i<n;i++)
if(!col[i] && !dg[u-i+n] && !udg[u+i])
{
g[u][i]='Q';
col[i]=dg[u-i+n]=udg[u+i]=true;
dfs(u+1);
g[u][i]='.';
col[i]=dg[u-i+n]=udg[u+i]=false;
}
}
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;
}
第二种搜索方式(按每一格搜索)
/*
第一种搜索顺序
定义纵坐标为y轴,横坐标为x轴,u是每一层的状态,i是枚举每一列的状态,那么y:u, x:i;
正对角线y = x+b -> b = y-x+n; 反对角线是 y = -x+b -> b = x+y;那么应该是dg[n+u-i],udg[u+i].
*/
#include <iostream>
using namespace std;
const int N = 20; // 对角线的数量是n*2,所以要开20
int n;
char g[N][N];
bool col[N],row[N],dg[N],udg[N];//col是行,row是列,dg是正对角线,udg是反对角线
void dfs(int u)
{
// 1.边界 2.递归 3.恢复现场
if(u == n)
{
for(int i = 0; i < n; i++) cout << g[i] << endl;
cout << endl;
return ;
}
// y:u, x:i
for(int i=0;i<n;i++)
if(!col[i] && !dg[u-i+n] && !udg[u+i])
{
g[u][i]='Q';
col[i]=dg[u-i+n]=udg[u+i]=true;
dfs(u+1);
g[u][i]='.';
col[i]=dg[u-i+n]=udg[u+i]=false;
}
}
void dfs2(int x,int y,int s)
{
if(y==n) y=0,x++;
if(x==n)
{
if(s==n)
{
for(int i=0;i<n;i++) cout<<g[i]<<endl;
cout<<endl;
}
return ;
}
//不放
dfs2(x,y+1,s);
//放
if(!col[x] && !row[y] && !dg[y-x+n] && !udg[y+x])
{
g[x][y]='Q';
col[x]=row[y]=dg[y-x+n]=udg[y+x]=true;
dfs2(x,y+1,s+1);
g[x][y]='.';
col[x]=row[y]=dg[y-x+n]=udg[y+x]=false;
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
g[i][j] = '.';
//dfs(0); // 按行枚举
dfs2(0,0,0); //按每一格枚举
return 0;
}