HJ43 迷宫问题

描述

迷宫问题_牛客题霸_牛客网

有一个 hh 行 ww 列的网格,我们使用 (i,j)(i,j) 表示网格中从上往下数第 ii 行和从左往右数第 jj 列的单元格。每个方格要么是可以通过的空方格 '0''0' ,要么是不可通过的墙方格 '1''1' ,特别的,网格的四周都是墙方格,你可以沿着空方格上下左右随意移动:从 (x,y)(x,y) 向上移动一格即抵达 (x−1,y)(x−1,y) 、向下移动一格即抵达 (x+1,y)(x+1,y) 、向左移动一格即抵达 (x,y−1)(x,y−1) 、向右移动一格即抵达 (x,y+1)(x,y+1) 。

现在,你位于迷宫的入口 (0,0)(0,0) ,想要前往终点 (h−1,w−1)(h−1,w−1) 。请输出一条从起点到终点的可行路径。

保证起点和终点一定为空方格,你始终可以找到且能唯一找到一条从起点出发到达终点的可行路径。

输入描述:

第一行输入两个整数 h,w(1≦h,w≦100)h,w(1≦h,w≦100) 代表迷宫的行数和列数。

此后 hh 行,第 ii 行输入 ww 个整数 ai,1,ai,2,...,ai,w(0≦ai,j≦1)ai,1​,ai,2​,...,ai,w​(0≦ai,j​≦1) 代表迷宫的布局。其中,ai,j=0ai,j​=0 表示单元格 (i,j)(i,j) 是空方格,ai,j=1ai,j​=1 表示单元格 (i,j)(i,j) 是墙方格。

输出描述:

输出若干行,第 ii 行输出两个整数 xi,yixi​,yi​ ,表示路径的第 ii 步抵达的单元格坐标为 (xi,yi)(xi​,yi​) 。

你需要保证输出的路径是符合题目要求的,即从起点 (0,0)(0,0) 出发,到达终点 (h−1,w−1)(h−1,w−1) ,且路径上每个单元格都是空方格,行走的单元格都是彼此相邻的。

输入:

复制代码
5 5
0 1 0 0 0
0 1 1 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

输出:

复制代码
(0,0)
(1,0)
(2,0)
(2,1)
(2,2)
(2,3)
(2,4)
(3,4)
(4,4)

输入:

复制代码
5 5
0 1 0 0 0
0 1 0 1 0
0 0 0 0 1
0 1 1 1 0
0 0 0 0 0

输出:

复制代码
(0,0)
(1,0)
(2,0)
(3,0)
(4,0)
(4,1)
(4,2)
(4,3)
(4,4)

代码思路

java 复制代码
import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int m = in.nextInt(); // 地图的行数
        int n = in.nextInt(); // 地图的列数
        int[][] nums = new int[m][n]; // 存储地图信息,0表示通路,1表示障碍物
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                nums[i][j] = in.nextInt(); // 读入地图内容
            }
        }

        // 用于记录当前路径的坐标序列
        List<Integer[]> list = new ArrayList<>();
        list.add(new Integer[]{0, 0}); // 起点加入路径

        boolean[][] visit = new boolean[m][n]; // 标记某个位置是否已经访问过,避免重复搜索

        // 调用 DFS 寻找路径
        dfs(list, nums, visit, m, n, 0, 0);

        // 移除起点最后一次重复记录
        list.remove(list.size() - 1);

        // 输出路径中所有坐标
        for (Integer[] path : list) {
            System.out.println("(" + path[0] + "," + path[1] + ")");
        }
    }

    // 定义四个方向:下、上、右、左
    public static Integer[][] direction = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};

    /**
     * DFS 方法,递归搜索路径
     * @param list 当前路径上的坐标列表
     * @param nums 地图矩阵
     * @param visit 标记数组,标记访问过的位置
     * @param m 地图行数
     * @param n 地图列数
     * @param x 当前行坐标
     * @param y 当前列坐标
     * @return 是否找到从起点到终点的路径
     */
    public static boolean dfs(List<Integer[]> list, int[][] nums, boolean[][] visit, int m, int n, int x, int y) {
        // 边界条件和障碍判断
        if (x < 0 || x >= m || y < 0 || y >= n || nums[x][y] == 1 || visit[x][y]) {
            // 这里判断是否到达终点(右下角)
            if (x == m && y == n - 1 || x == m - 1 && y == n) {
                return true;
            } else {
                return false; // 越界或障碍,返回false
            }
        }

        visit[x][y] = true; // 标记当前位置已访问

        // 遍历四个方向
        for (Integer[] dir : direction) {
            int newx = x + dir[0];
            int newy = y + dir[1];
            list.add(new Integer[]{newx, newy}); // 将新坐标加入路径
            if (dfs(list, nums, visit, m, n, newx, newy)) {
                return true; // 找到一条通路,立即返回
            }
            list.remove(list.size() - 1); // 回溯,移除当前方向坐标
        }

        return false; // 四个方向都没找到通路,返回false
    }
}
相关推荐
Tisfy3 小时前
LeetCode 3345.最小可整除数位乘积 I:暴力枚举(从n开始尝试)
数学·算法·leetcode·题解·枚举
DolphinDB智臾科技3 小时前
告别 TB 级数据搬运:DolphinDB 滤波算法库,重塑物联网数据价值链
物联网·算法
可编程芯片开发4 小时前
基于双PI控制器结构的六步逆变器供电无刷直流电机调速simulink仿真
算法
Sagittarius_A*4 小时前
后量子密码|通识认知 02|量子威胁核心原理:Shor 算法如何击穿传统公钥密码
算法·信息安全·密码学·量子计算
青山木4 小时前
Hot 100 --- 在排序数组中查找元素的第一个和最后一个位置
java·数据结构·算法·leetcode
其美杰布-富贵-李4 小时前
聚类算法详解:K-means、层次聚类与 DBSCAN
算法·机器学习·kmeans·聚类
碧海银沙音频科技研究院5 小时前
4 BES2710编译环境搭建方法
嵌入式硬件·算法
mifengxing5 小时前
LeetCode 238 除自身以外数组的乘积|无除法O(n)时间+O(1)空间双解法
java·算法·leetcode
依然鸣5 小时前
PTA团体程序设计天梯赛L2真题讲解L2-045-048
数据结构·c++·经验分享·学习·算法·pat考试·pat
丢掉幻想准备斗争6 小时前
5.5树与二叉树的应用
算法