深度优先遍历,也称深度优先搜索(简称DFS),它的主要思想是全部遍历,比如在一个房间里有厨房、卧室、浴室,厨房中有柜子,碗橱,卧室有床、桌子,此时你的一把钥匙不小心弄丢了,这时你便需要去将房间的每一个角落都翻一遍,这便是深度优先搜索。
为了更好的理解深度优先搜索,下面引进我之前做的一个题:
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
6 9
....#.
.....#
......
......
......
......
......
#@...#
.#..#.
11 9
.#.........
.#.#######.
.#.#.....#.
.#.#.###.#.
.#.#..@#.#.
.#.#####.#.
.#.......#.
.#########.
...........
11 6
..#..#..#..
..#..#..#..
..#..#..###
..#..#..#@.
..#..#..#..
..#..#..#..
7 7
..#.#..
..#.#..
###.###
...@...
###.###
..#.#..
..#.#..
0 0
Sample Output
45
59
6
13
简单理解为:’.’是路,‘#’是墙,找出所能走的最大路的步数。
首先每走一步都可以选择四个方向,我们可以理解为四个向量,分别是:(0,1)(0,-1)(1,0)(-1,0)在这里引进一个二维数组用来储存他们的方向(一一对应):
int fx[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
每走一步为了不给自己去留后路,我们把经过的点标记为%(此时不要忘记@也要变成%)。
定义一个字符map二维数组用来储存字符,从中找出开始位置’@’标记的x,y位置。
定义一个函数dfs,,将x,y这个点的地图上变成’%’,要想想下一个点的位置,可以向上走,向下走,向左走,向右走,有四个方向,这就用到我们之前定义的四个方向,但是要满足一定的条件(不能超线,并且要变的那个点不能是墙),接下来就是递归,满足这个条件的变成%,并且去寻找下一个点,找到满足条件的点之后将这个点变成%就一直找下去,直到四周都不满足条件,此时所有可以遍历的.都变成了%,最后全部遍历找到%,求出数。
上代码:
#include <iostream>
using namespace std;
char map[25][25];
int fx[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 }; //四个方向向量
int a, b; //边界
void dfs(int x, int y) {
map[x][y] = '%';
for (int i = 0; i < 4; i++) {
int xx = x + fx[i][1];
int yy = y + fx[i][0];
while (xx < b && xx >= 0 && yy >= 0 && yy < a && map[xx][yy] == '.') {
dfs(xx, yy); //调用递归
}
}
}
int main() {
ios::sync_with_stdio(false); //快速输入输出
int x, y;
while (cin >> a >> b && a && b) {
for (int i = 0; i < b; i++) {
for (int j = 0; j < a; j++) {
cin >> map[i][j];
if (map[i][j] == '@') {
x = i;
y = j;
}
}
}
dfs(x, y);
int num = 0;
for (int i = 0; i < b; i++) { //遍历全部找%,数值便是要求的值。
for (int j = 0; j < a; j++) {
if (map[i][j] == '%') {
num++;
}
}
}
cout << num << endl;
}
return 0;
}