回溯算法走迷宫(Java版)

Posted ZSYL

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了回溯算法走迷宫(Java版)相关的知识,希望对你有一定的参考价值。

迷宫问题 请参考 超详解的迷宫问题(Java版)

题目描述

现在有一个大小为n*m的迷宫,你正在(1,1)点,你想要前往右下方(n,m),并且每次只能向上下左右四个方向走一步,请问有多少种方案。

输入输出

输入:

第一行输入两个正整数N, M(N <=10,M<=10)分别表示迷宫大小,接下来n行每行m个字符字符为’.’或者’#’,’#’代表这个点不能走,请你输出题目描述中的合法的方案数。(一种方案为合法要求其方案中同一个点仅仅被走过一次)

输出:

一个整数为方案数(数据保证方案数小于1e7)

样例

10 2


#.

#.




输出:

32

代码展示

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Main {
    static char[][] map;  // 存储图
    static int n, m;  // 行数,列数
    static int[] orient = {0, 1, 0, -1, 0};  // 四个方向
    static boolean[][] vis;  // 标记数组
    static int sum = 0;  // 总数
    public static void main(String[] args) throws IOException {
    	// 提高读效率
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] s = br.readLine().split(" ");
        n = Integer.parseInt(s[0]);
        m = Integer.parseInt(s[1]);
        
        map = new char[n][m];
        for (int i = 0; i < n; i++) {
            map[i] = br.readLine().toCharArray();
        }
        
        vis = new boolean[n][m];  // 默认false
        dfs(0, 0);  // 递归
        System.out.println(sum);
    }
    public static void dfs(int i, int j) {
    	// 递归结束条件
        if (i == n-1 && j == m-1) {
            sum++;
            return;
        }
        // 遍历四个方向
        for (int k = 0; k < 4; k++) {
        	// 剪枝操作
            if (i < 0 || i > n-1 || j < 0 || j > m-1 || vis[i][j] || map[i][j] == '#')
                continue;
            vis[i][j] = true;  // 修改该点访问位为true
            dfs(i+orient[k], j+orient[k+1]);  // 从当前方向递归探索
            vis[i][j] = false;  // 回溯,当该点走不通,修改为false,以便循环更换其他方向递归
        }
    }
}

错误代码

我想用BFS模拟栈的执行过程,但是程序陷入死循环了,所以放出来,恳请大佬指教。

public static void bfs() {
    Stack<int[]> stack = new Stack<>();  // 后进先出,模拟递归栈
    stack.push(new int[]{0, 0});
    while (!stack.isEmpty()) {  // 栈不为空就一直循环
        int[] cur = stack.peek();  // 获取当前点,cur[0]:代表 横坐标 cur[1]:代表纵坐标
        // 到达终点
        if (cur[0] == n-1 && cur[1] == m-1) {
            sum++;
            continue;
        }
        // 从当前点向四个方向找可行的点
        int i;
        boolean flag = false;
        for (i = 0; i < 4; i++) {
            int row = cur[0]+orient[i];
            int column = cur[1]+orient[i+1];
            // 判断当前方向是否可以通过
            if (row < 0 || row > n-1 || column < 0 || column > m-1 || vis[row][column] || map[row][column] == '#')
                continue;
            flag = true;
            stack.push(new int[]{row, column});
            vis[row][column] = true;
        }
        // 如果未找到可行方向,则将栈顶元素 pop,修改为 -1
        if (!flag) {
            cur = stack.pop();  // 出栈
            vis[cur[0]][cur[1]] = false;  // 回溯
        }
    }
}

感谢

小猪梦想变大牛

加油!

以上是关于回溯算法走迷宫(Java版)的主要内容,如果未能解决你的问题,请参考以下文章

兔年之兔子走迷宫 用一个小游戏对回溯法进行实现 | C++

回溯算法之迷宫问题

Java --- 走迷宫

回溯算法背包问题(Java版)

数据结构与算法:迷宫回溯和八皇后问题

算法浅谈——走迷宫问题与广度优先搜索