黑马程序员----经典问题(走迷宫)

来源:互联网 发布:广州公务员待遇 知乎 编辑:程序博客网 时间:2024/05/16 02:28

------- android培训java培训、期待与您交流! ----------

迷宫问题

描述

求迷宫中从入口到出口的所有路径是一个经典的程序设计问题。由于计算机解迷宫时,通常用的是“穷举求解”的方法,即从入口出发,顺着某一个方向向前探索,若能走通,则继续往前走;否则沿着原路退回,换一个方向再继续探索,直至所有可能的通路都探索到为止。为了保证在任何位置都能沿原路退回,显然需要用一个栈来保存从入口到当前位置的路径。因此,这样的题目可以用栈来解决,当然也可以用类似的方法完成求解。

如一个典型的问题是:迷宫求最短路径。只能走上、下,左、右四个方向。

输入

输入只有一个用例。

第一行为迷宫大小,n,m,即n行m列,

第二行为起点位置,

第三行为终点位置,

接下来的为迷宫图,1表示墙壁,0表示通道

输出

输出从起点到终点的最短路径,即最少走的步数。

样例输入

10 10
2 2
9 9
1 1 1 1 1 1 1 1 1 1
1 0 0 1 0 0 0 1 0 1
1 0 0 1 0 0 0 1 0 1
1 0 0 0 0 1 1 0 0 1
1 0 1 1 1 0 0 0 0 1
1 0 0 0 1 0 0 0 0 1
1 0 1 0 0 0 1 0 0 1
1 0 1 1 1 0 1 1 0 1
1 1 0 0 0 0 0 0 0 1
1 1 1 1 1 1 1 1 1 1

样例输出

14

首先我们用递归求解

import java.util.Scanner;public class Main {//用来保存在递归过程中所走的路径,如果为true表示走过,public static boolean flag[][] = new boolean[20][20];//用来表示地图public static int maze[][] = new int[20][20];public static int n ,m, endx, endy, startx, starty;//用来保存所有路径中的最小值public static int minx ;public static void main(String[] args) {Scanner sca = new Scanner( System.in );while( sca.hasNext() ){n = sca.nextInt(); //输入地图范围m = sca.nextInt();startx = sca.nextInt();//开始位置starty = sca.nextInt();endx = sca.nextInt();//结束位置endy = sca.nextInt();minx = 10000000;//初始值为最大值for( int i = 1; i <= n; i++ )for( int j = 1; j <= m; j++ ){flag[i][j] = false;maze[i][j] = sca.nextInt();}Find_path( startx, starty, 0 );//递归查找System.out.println( minx );}}//枚举四个方向public static int dir[] = { 0, 1, 0, -1, 0 };public static void Find_path( int x, int y, int step ) {if( x == endx && y == endy ) {//如果等于重点,则比较最小步数if( step < minx ) minx = step;return ;}//这里是一个小的优化,如果当前走的步数已经大于了最小步数,那么直接返回,这条路不用走下去if( step > minx ) return ;for( int i = 0; i < 4; i++ ) {//这里的四个方向分别是 (0,1),(1,0),(0,-1),(-1,0)int xx = dir[i] + x;int yy = dir[i+1] + y;//判断当前所走的地方是否越界,或者是否被走过,或者是墙壁不能走if( xx >= 1 && xx <= n && yy >= 1 && yy <= m  && !flag[xx][yy] && maze[xx][yy]==0 ){flag[xx][yy] = true;//把当前位置标记为true , 走过Find_path(xx, yy, step+1);//从当前位置进行递归flag[xx][yy] = false;//退回的时候标记还没走过}}}}


图画的不是很好,但至少能表现出递归的路线


下面是用队列写的,俗称BFS

package com.itheima;import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;public class Main {//用来保存在递归过程中所走的路径,如果为true表示走过,public static boolean flag[][] = new boolean[20][20];//用来表示地图public static int maze[][] = new int[20][20];public static int n ,m, endx, endy, startx, starty;//用来保存所有路径中的最小值public static int minx;public static void main(String[] args) {Scanner sca = new Scanner( System.in );while( sca.hasNext() ){n = sca.nextInt(); //输入地图范围m = sca.nextInt();startx = sca.nextInt();//开始位置starty = sca.nextInt();endx = sca.nextInt();//结束位置endy = sca.nextInt();minx = 10000000;//初始值为最大值for( int i = 1; i <= n; i++ )for( int j = 1; j <= m; j++ ){flag[i][j] = false;maze[i][j] = sca.nextInt();}Find_path( startx, starty );//递归查找System.out.println( minx );}}//枚举四个方向public static int dir[] = { 0, 1, 0, -1, 0 };public static void Find_path( int x, int y ) {Queue<Node> queue = new LinkedList<Node>();queue.add( new Node( x,y,0 ) );flag[x][y] = true;while( !queue.isEmpty() ){Node a = queue.poll(); //出队列,找一个点进行四个方向枚举if( a.x == endx && a.y == endy ) {//找到终点位置minx = a.step;break;}for( int i = 0; i < 4; i++ ) {int xx = a.x + dir[i];int yy = a.y + dir[i+1];if( xx >= 1 && xx <= n && yy >= 1 && yy <= m  && !flag[xx][yy] && maze[xx][yy]==0 ){flag[xx][yy] = true;//把当前位置标记为true , 走过//进队列queue.add( new Node(xx, yy, a.step+1) );}}}}}class Node {public Node( int x, int y, int step ) {this.x = x;this.y = y;this.step = step;}public Node() {}int x, y, step;}


这BFS呢,是将一个节点不断的向四个方向扩展,最终找到目标节点。

0 0
原创粉丝点击