例题:走迷宫
1.需要一个终止条件,
2.需要四个搜索方向:上下左右;
3.并且需要使用bool进行标记一个方向是否访问过;
4.如果需要找到多个可行解,那么如果该方向可行,需要取消标记。如果只需要也给可行解,则不需要取消标记
问题描述
有一个二维迷宫,n行m列,‘s’表示迷宫的起点,‘T’表示迷宫的终点,‘#’表示围墙,‘.’表示通路。
现在从S出发,找出路径,并且打印出来
输入格式
第一行输入n,m(1<=n,m<=10)表示迷宫的行列大小。
接下来输入n行字符串表示迷宫。
输出格式
一个整数,表示走出迷宫的方法数
样例输入1
5 6 ....S* .***.. .*..*. *.***. .T....
样例输出1
....m* .***mm .*..*m *.***m .Tmmmm
思路
可以用深度优先搜索(递归思想)来解决,从起点出发,下一个点只有四个方向,如果遇墙就结束,如果遇点就前进并标记(搜索完该支路后消除标记,供后面搜索判断),直到遇到‘T’,
AC代码:
#include<iostream>
using namespace std;
int n, m;
char maze[110][110];
bool vis[110][110];
bool in(int x, int y) {
return 0 <= x && x < n && 0 <= y && y < m;//n和m分别为输入的边界;
}
bool dfs(int x, int y) {
int n, m;
//结束条件:找到终点T
if (maze[x][y] == 'T') {
return true;
}
vis[x][y] = true;//表示这个地方已经走过了;
maze[x][y] = 'm';//表示路径
int tx = x, ty = y - 1;//定义一个初始访问方向,向上走;从终点寻找起点
//向上走
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
//判断1.访问区域在迷宫类,2.访问的地方不是障碍*,3.判断这个地方没有被访问过;
if (dfs(tx, ty)) return true;
}
tx = x - 1, ty = y;//向左走;
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
if (dfs(tx, ty)) return true;
}
tx = x;ty = y + 1;//向下走
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
if (dfs(tx, ty)) return true;
}
tx = x + 1;ty = y;//向右走;
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty]) {
if (dfs(tx, ty)) return true;
}
vis[x][y] = false;//失败则标记一下;
maze[x][y] = '.';//之前设置为了m,现在还原,表示这里不是通往终点的路
return false;
}
int main() {
cin >> m >> n;//m为行,n为每行有几个
for (int i = 0;i < m;i++) {
for (int j = 0;j < n;j++) {
cin >> maze[j][i];
}
}
int x, y;
//找到起点坐标
for (int i = 0;i < m;i++) {
for (int j = 0;j < n;j++) {
if (maze[j][i] == 'S')
x = j,y = i;
}
}
if (dfs(x, y)) {
for (int i = 0;i < m;i++) {
for (int j = 0;j < n;j++) {
cout << maze[j][i];
}
cout << endl;
}
}
else cout << "NO!" << endl;
}
优化:
把四个方向,写出一种循环,用二维数组表示方向;并且再加个取模即可
int dir[4] [2]={{0,-1},{-1,0},{0,1},{1,0}}分别表示上左下右;方向用逆时针;
四组数据,每组两个数据;每组第一个表示x(对应下标为0),第二个表示y(对应下标为1)
for (int i = 0;i < 4;i++) {
int tx = x + dir[i][0];
int ty = y + dir[i][1];
if (in(tx, ty) && maze[tx][ty] != '*' && !vis[tx][ty])
if (dfs(tx, ty)) return true;
}//四个方向依次访问;两串代码本质没有区别,时间复杂度没有区别;之后可以减枝优化搜索