『算法拾遗』深度优先搜索(1):初尝 DFS
还是从走迷宫开始
与 BFS 不同,DFS 非常简单:每当进入一个状态,生产出第一个子状态后,直接函数递归进去,直到走到头,然后回溯回来,再尝试第二个状态
其实就是队列和栈的区别,BFS 是产生一个状态就扔到队列里,DFS 是产生一批状态,先把它们压入栈,然后取一个出来处理
而函数递归就是一种栈,所以 DFS 实际上并不需要专门声明一个栈出来
还是拿最简单的 hdu 1312 Red and Black 来说事
点击查看题目
-
Problem Description
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A man is standing on a black tile. From a tile, he can move to one of four adjacent tiles. But he can’t move on red tiles, he can move only on black tiles.
Write a program to count the number of black tiles which he can reach by repeating the moves described above.
-
Input
The input consists of multiple data sets. A data set starts with a line containing two positive integers W and H; W and H are the numbers of tiles in the x- and y- directions, respectively. W and H are not more than 20.
There are H more lines in the data set, each of which includes W characters. Each character represents the color of a tile as follows.
‘.’ - a black tile
‘#’ - a red tile
‘@’ - a man on a black tile(appears exactly once in a data set) -
Output
For each data set, your program should output a line which contains the number of tiles he can reach from the initial tile (including itself). -
Sample Input
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
366 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0 -
Sample Output
1
2
3
445
59
6
13
简单地说还是走迷宫,遍历所有可能的位置,并且数格子,大概的算法如下
- 从当前点开始向四周观望
- 枚举它能到达的点,每枚举出来一个就调用第一步
1 |
|
回溯状态:八皇后
好!你已经基本知道 DFS 是怎么一回事了,来看一道经典题目:P1219八皇后
点击查看题目
-
题目描述
一个如下的 的跳棋棋盘,有六个棋子被放置在棋盘上,使得每行、每列有且只有一个,每条对角线(包括两条主对角线的所有平行线)上至多有一个棋子。
上面的布局可以用序列 来描述,第 个数字表示在第 行的相应位置有一个棋子,如下:
行号
列号
这只是棋子放置的一个解。请编一个程序找出所有棋子放置的解。
并把它们以上面的序列方法输出,解按字典顺序排列。
请输出前 个解。最后一行是解的总个数。
-
输入格式
一行一个正整数 ,表示棋盘是 大小的。
-
输出格式
前三行为前三个解,每个解的两个数字之间用一个空格隔开。第四行只有一个数字,表示解的总数。
-
样例 #1
-
样例输入 #1
1
6
-
样例输出 #1
1
2
3
42 4 6 1 3 5
3 6 2 5 1 4
4 1 5 2 6 3
4
-
对于这道题,可以按行搜索,在搜索第 行时,尝试在每一列都放,放完记得要做占领标记,然后继续搜索第 行,回溯回来第 行的时候,先撤销原来的点,再占领新点,然后再继续搜索
1 |
|