对于深度优先搜索,我看了很久还是无法理解,近日终于独立解决了一道题。
我用的是递归形式,代码如下:
#include<iostream>
#include<cstring>
using namespace std;
#define M 10
struct point{
int x; int y;
};
point ds[8] = {-2,1,-1,2,1,2,2,1,2,-1,1,-2,-1,-2,-2,-1};
bool used[M][M] = {0};
int m, n,mcount;
int solutions;
void Dfs(int i, int j)
{
for (int t = 0; t < 8; t++)
{
int i_next = i + ds[t].x;
int j_next = j + ds[t].y;
if ((i_next >= 0 && i_next <= n - 1) && (j_next >= 0 && j_next <= m - 1) && used[i_next][j_next] == 0)
{
if (mcount != n*m-1)
{
mcount++;
used[i_next][j_next] = mcount;
Dfs(i_next, j_next);
used[i_next][j_next] = 0;
mcount--;
}
else
{
solutions++;
}
}
}
}
int main()
{
int T;
int x, y;
cin >> T;
while (T--)
{
cin >> n >> m >> x >> y;
memset(used,0,sizeof(used));
mcount = 1;
solutions = 0;
used[x][y] = 1;
Dfs(x,y);
cout << solutions << endl;
}
return 0;
}
任何DFS只需要通过下面几步就可以实现,无论是递归还是非递归方式。
如下:
1、find(right):在树的当前层,横向遍历,尝试找到ok的节点。(这一步通常被叫做剪枝,只留下ok的。)
2、forward(down):若在当前层找到ok的结点,并且当前层不是最后一层:把ok的节点放到当前层;进入下一层第一个结点。跳到find
3、done(right):若在当前层找到ok的结点,并且当前层是最后一层:打印出结果;进入当前层的下一个结点。跳到find
4、back(up):在当前层没有找到ok的节点:返回上一层当前结点的下一个兄弟节点。跳到find
其实最重要的是find。然后后面的forward、done、back只是用来控制搜索走向。这四步可以进一步总结成两步。 为了了解算法,我想最好的切入方式是从一些实例开始。下面分别从八皇后以及马走日等问题做为切入点来分析DFS