1、常见迷宫问题

回溯、dfs:是否有解,唯一解等问题

//递归写法public static boolean dfs(char[][] m, boolean[][] vis, Node start, Node end) {if (start.x == end.x && start.y == end.y) {return true;}vis[start.x][start.y] = true;for (int i = 0; i < 4; i++) {int x = start.x + xx[i];int y = start.y + yy[i];if (check(m, vis, x, y)) {if (dfs(m, vis, new Node(x, y), end) )  //有一个trur就行了return true;}}return false;}//栈模拟写法public static boolean dfs2(char[][] m, boolean[][] vis, Node start, Node end) {vis[start.x][start.y] = true;Deque<Node> st = new LinkedList<>();  //模拟栈st.push(start);while (!st.isEmpty()) {Node tmp = st.pop();if (tmp.x == end.x && tmp.y == end.y) {return true;}vis[tmp.x][tmp.y] = true;//tmp.print();for (int i = 0; i < 4; i++) {int x = tmp.x + xx[i];int y = tmp.y + yy[i];if (check(m, vis, x, y)) {st.push(new Node(x, y));}}}return false;}

BFS:走出迷宫的最短路径:

class Node {int x, y;//int len; //有时需要记录深度//Node pre; //有事需要记录路劲
}public static int BFS(char[][] m, boolean[][] vis, Node start, Node end,) {Queue<Node> q = new LinkedList<>();q.offer(new Node(start.x, start.y, 0));   // 起点加入队列while (!q.isEmpty()) {Node tmp = q.poll();vis[tmp.x][tmp.y] = true;if (tmp.x == end.x && tmp.y == end.y) {  //到大终点return tmp.len;}for (int i = 0; i < 4; i++) {      // 上下左右四个方向 并检查坐标的合法性及是否访问int x = tmp.x + xx[i];int y = tmp.y + yy[i];if (check(m, vis, x, y, c)) {Node newTmp = new Node(x, y, tmp.len + 1);q.offer(newTmp);}}}return -1;}

2、一道难题

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网

这是一个关于二维迷宫的题目。我们要从迷宫的起点 'S' 走到终点 'E',每一步我们只能选择上下左右四个方向中的一个前进一格。 'W' 代表墙壁,是不能进入的位置,除了墙壁以外的地方都可以走。迷宫内的 'D' 代表一道上锁的门,只有在持有钥匙的时候才能进入。而 'K' 则代表了钥匙,只要进入这一格,就会自动地拿到钥匙。最后 '.' 则是代表空无一物的地方,欢迎自在的游荡。

本题的迷宫中,起点、终点、门跟钥匙这四个特殊物件,每一个恰好会出现一次。而且,此迷宫的四周 (最上面的一行、最下面的一行、最左边的一列以及最右边的一列) 都会是墙壁。

请问,从起点到终点,最少要走几步呢?

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;class Node {int x, y, len;public Node(int a, int b, int l) {x = a;y = b;len = l;}public Node() {}public void print() {System.out.println(x + " " + y + " " + len);}
}public class Main {static int[] xx = new int[]{1, 0, -1, 0};static int[] yy = new int[]{0, 1, 0, -1};public static void main(String[] args) {Scanner in = new Scanner(System.in);int m = in.nextInt();int n = in.nextInt();char[][] a = new char[m][n];boolean[][] vis = new boolean[m][n];in.nextLine();Node start = new Node(), end = new Node(-1, -1, 0), key = new Node(-1, -1, 0), men = new Node(-1, -1, 0);for (int i = 0; i < m; i++) {String s = in.nextLine();for (int j = 0; j < n; j++) {a[i][j] = s.charAt(j);if (s.indexOf('S') != -1) {start.x = i;start.y = s.indexOf('S');}if (s.indexOf('K') != -1) {key.x = i;key.y = s.indexOf('K');}if (s.indexOf('E') != -1) {end.x = i;end.y = s.indexOf('E');}if (s.indexOf('D') != -1) {men.x = i;men.y = s.indexOf('D');}}}int zeroStep = BFS(a, vis, start, end, 'D');//System.out.println(zeroStep);//System.out.println();fillFalse(vis);int firstStep = BFS(a, vis, start, key, 'D');fillFalse(vis);//System.out.println(firstStep);int secondStep = BFS(a, vis, key, men, ' ');fillFalse(vis);//System.out.println(secondStep);int thireStep = BFS(a, vis, men, end, ' ');//System.out.println(zeroStep + " " + firstStep + " " + secondStep + " " + thireStep);int res = firstStep + secondStep + thireStep;if (zeroStep != -1 && zeroStep < res) {System.out.println(zeroStep);return;}if ((firstStep == -1 || secondStep == -1 || thireStep == -1) && zeroStep == -1) {System.out.println(-1);return;} elseSystem.out.println(firstStep + secondStep + thireStep);//System.out.println("res:"+firstStep +" " +secondStep+" "+thireStep);}public static int BFS(char[][] m, boolean[][] vis, Node start, Node end, char c) {Queue<Node> q = new LinkedList<>();q.offer(new Node(start.x, start.y, 0));while (!q.isEmpty()) {Node tmp = q.poll();//tmp.print();vis[tmp.x][tmp.y] = true;if (tmp.x == end.x && tmp.y == end.y) {return tmp.len;}for (int i = 0; i < 4; i++) {int x = tmp.x + xx[i];int y = tmp.y + yy[i];if (check(m, vis, x, y, c)) {Node newTmp = new Node(x, y, tmp.len + 1);q.offer(newTmp);}}}return -1;}public static boolean check(char[][] m, boolean[][] vis, int x, int y, char c) {if (x < 0 || y < 0 || x > m.length - 1 || y > m[0].length - 1 ||m[x][y] == c || vis[x][y] || m[x][y] == 'W') {  //w表示障碍return false;}return true;}public static void fillFalse(boolean[][] vis) {for (int i = 0; i < vis.length; i++) {for (int j = 0; j < vis[0].length; j++) {vis[i][j] = false;}}}
}

总结:

1、无障碍,右下走,代价相等 (dp[i][j] = dp[i][j-1] + dp[i-1][j]  或者组合公式)

变式:有障碍,右下走,代价相等 dp即可

变式:无障碍,右下走,代价不等 dp即可dp[i][j] = min(dp[i][j-1] + dp[i-1][j]) + a[i][j] 

变式:无障碍,右下走,代价不等并可能为负值

题目示例:leetcode 174. 地下城游戏 (反向推)

2、有障碍,任意走,代价相等(大于等于0)(一般性迷宫)

解法很经典:DFS或BFS

迷宫问题总结(算法)相关推荐

  1. Java自动计算迷宫正确路线算法源码

    简介: Java自动计算迷宫正确路线算法源码,首先迷宫需要满足存在开始标识和结束标识与墙标识,然后设置好行数与列数就可以开始计算正确路线了,采用的是为二维数组然后走遍所有路线的方式. 网盘下载地址: ...

  2. 【算法】机器人走迷宫(适用于走迷宫、最短路径算法)-20200412

    标题:机器人走迷宫(适用于走迷宫.最短路径算法) 问题描述: 一块矩形方格,含有障碍和可通行格子,求从某一点到另外一点的最短距离?N*M的矩阵: 其中,1代表障碍,0代表可通行:示例:给定二维矩阵 0 ...

  3. 迷宫路线寻找算法的matlab仿真

    1.问题描述: 迷宫创建算法和迷宫路径寻找算法 2.部分程序: % Clean up. clc;  close all;  clear all;  fontSize = 20;  % Font siz ...

  4. prim算法_自动生成随机迷宫(1)prim算法

          "程序 = 数据  + 算法",一款好的作品不单单是代码的堆砌,还有其灵魂的部分,那就是算法:算法是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机 ...

  5. python自动寻路算法_PHP生成迷宫及自动寻路算法详解

    如何使用PHP生成迷宫以及寻路求解?本文主要介绍了PHP生成迷宫及自动寻路算法,并对PHP生成迷宫及自动寻路算法详解.希望对大家有所帮助. 本文实例讲述了PHP树的深度编历生成迷宫及A*自动寻路算法. ...

  6. 实验三、prim算法生成迷宫,A*算法解迷宫(实验准备)

    目录 实验要求: 算法简介: prim算法: A*算法: 实验要求: 该项目的主要要求是:首先生成一个迷宫,要求随机生成.而生成迷宫有深度优先算法.prim算法.递归分割算法等.老师说建议使用prim ...

  7. 【算法】机器人走迷宫破壁解法(适用于走迷宫、最短路径算法)-20200412

    标题:机器人走迷宫破壁解法(适用于走迷宫.最短路径算法)-20200412 问题描述: 一块矩形方格,含有障碍和可通行格子,求从某一点到另外一点的最短距离?N*M的矩阵: 其中,1代表障碍,0代表可通 ...

  8. c语言 迷宫深度遍历 算法,图的遍历迷宫生成算法浅析

    1. 引言 在平常的游戏中,我们常常会碰到随机生成的地图.这里我们就来看看一个简单的随机迷宫是如何生成. 2. 迷宫描述随机生成一个m * n的迷宫,可用一个矩阵maze[m][n]来表示,如图:   ...

  9. a*算法迷宫 c++_算法竞赛专题解析(12):搜索基础

    搜索 搜索,就是查找解空间,它是"暴力法"算法思想的具体实现. 文章目录: 01 搜索简介 02 搜索算法的基本思路 03 BFS的性质和代码实现 04 DFS的常见操作和代码实现 ...

  10. [迷宫中的算法实践]迷宫生成算法——Prim算法

    普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (graph theory)), ...

最新文章

  1. Unity Shaders
  2. Docker核心技术 1
  3. java中解密的思想_北大青鸟翔天解密,Java核心思想两大点
  4. 我的Go+语言初体验——【四、版本更新环境变量配置】
  5. 【POI2011】LIZ-Lollipop 【构造】
  6. 【Python】ffmpeg模块处理视频、音频信息
  7. 数据倾斜是什么以及造成的原因?
  8. LINUX下查看CPU使用率的命令[Z]
  9. 学习C++必须掌握的概念
  10. 【C++】常用排序算法
  11. Lytain:PCWin10纯净专业版重装与程序员的高效部署
  12. Arcgis一些操作
  13. 农场派对(party)(信息学奥赛一本通 1497)
  14. 常见js针对浏览器之间的兼容问题
  15. jmeter性能测试2-模拟多用户登录
  16. java统计误码率_MATLAB通信工具箱来计算误码率
  17. 腾讯地图产业版 WeMap 官网正式发布
  18. 小米怎么解锁,有什么相关教程
  19. 电子书如何通过邮箱传入kindle
  20. python-重难点知识汇总

热门文章

  1. React中使用微信分享
  2. prev~siblings选择器
  3. 【微信小程序】动画实现字幕滚动
  4. 大学生,就业or择业?
  5. 计算机类各专业就业方向,计算机各专业就业前景
  6. 卸料装置弹性零件的计算方法_弹性卸料装置的基本零件包括
  7. 学习 SpringCloud 服务消费者(rest+ribbon)小结
  8. 基于5G技术特点预测未来生活应用场景
  9. DELPHI中Showmodal与Show的区别(转载)
  10. java 后端学习路线(简化)