对于DFS在刚接触时因一句不撞南墙不回头就理解的透彻了许多,DFS也许更像是一种特殊的暴力方法,可以理解为对每条可行的路都尝试一遍:如左图的标记:从节点1开始,先1→2→3,在节点三没路走了便回退到节点2,在节点2也没可行的路走于是回退到节点1,又从1→4→5→6,到6无路可走一步步回退到4,即又从4→7→8....以此往复。所以DFS可以用栈来表现这一回退和搜索的过程(进栈弹栈操作),也可以用递归操作来实现,于是我这只蒟蒻就用递归的写法写了一些板子题供大家参考。
第一道经典八皇后问题:在一个N*N的棋盘上放置N个皇后,每个皇后的攻击范围为与其在同一列同一行和对角线上如图:
即为这样的米字型攻击区域,那么剩下的绿色的格子才能放置第二个皇后,现在给出一个棋盘大小N,求N个皇后放置的方案数;
经典的搜索板子题,可以发现对应每行和对应每列只能放置一个皇后,而对角线的攻击范围,我们可以发现有一条对角线的特征为(x-y)为定值,另一条对角线的特征为x+y为定值。因此我们分别用四个数组的状态来模拟该攻击区域是否能放置皇后,代码如下:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e7+5;
int a[1000][1000],x_[5]={1,-1,0,0},y_[5]={0,0,1,-1},cnt=0,n;//x_、y_数组一起并用模拟上下左右的方向
bool y[1000],yx[1000],xy[1000];// y数组模拟列 yx模拟y-x的对角线 xy模拟y+x的对角线
void dfs(int x){
if(x==n+1){
cnt++;
return ;
}
for(int i=1;i<=n;i++){//即对于从[x][1]→[x][n]寻找每个可行的位置
if(!y[i]&&!yx[x-i+200]&&!xy[x+i]){
y[i]=1;
yx[x-i+200]=1;
xy[x+i]=1;//标记该位置已被选中
dfs(x+1);//进行下一行的搜索
y[i]=0;
yx[x-i+200]=0;
xy[x+i]=0;//恢复上一行的标记
}
}
return ;//return就是当1->n没有位置可以选的时候返回上一行重新选择
}
signed main(){
cin>>n;
dfs(1);
cout<<cnt<<endl;
}
于是简单的N皇后问题我们递归方法DFS就解决了,洛谷上P1219八皇后问题就不止是问放置的方案数,还有前三种放置的方法,因此对于前三种输出还要处理,话不多说直接上代码注释:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e7+5;
int a[1000][1000],x_[5]={1,-1,0,0},y_[5]={0,0,1,-1},cnt=0,n;//x_、y_数组一起并用模拟上下左右的方向
bool y[1000],yx[1000],xy[1000];// y数组模拟列 yx模拟y-x的对角线 xy模拟y+x的对角线
void dfs(int x){//由于还要查询前三种放置方法,因此模拟一个棋盘a[][];
if(x==n+1){
cnt++;
if(cnt>3){
return;
}
else{
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(a[i][j]==1){
cout<<j<<" ";
}
}
}
cout<<endl;
return ;
}
}
for(int i=1;i<=n;i++){//即对于从[x][1]→[x][n]寻找每个可行的位置
if(!y[i]&&!yx[x-i+200]&&!xy[x+i]){
y[i]=1;
a[x][i]=1;//同理 如果该点能放置皇后就记录a[x][i]=1;并在深搜后回溯
yx[x-i+200]=1;
xy[x+i]=1;//标记该位置已被选中
dfs(x+1);//进行下一行的搜索
y[i]=0;
yx[x-i+200]=0;
a[x][i]=0;
xy[x+i]=0;//恢复上一行的标记
}
}
return ;//return就是当1->n都没有放置方法就回溯到上一层
}
signed main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
a[i][j]=0;
}
}
dfs(1);
cout<<cnt<<endl;
}
至于BFS的写法本蒟蒻还没写出来(太菜了别骂了),明天会更新P1443马的遍历以及补充一些DFS模板题供各位大佬食用。
传送门:
八皇后问题:[USACO1.5]八皇后 Checker Challenge - 洛谷
马的遍历:马的遍历 - 洛谷