深度优先搜索—走迷宫

例题:走迷宫

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;
     }//四个方向依次访问;两串代码本质没有区别,时间复杂度没有区别;之后可以减枝优化搜索

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ou_fan

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值