华为机试 迷宫最短路径

闯迷宫
 
描述:

sun所在学校每年都要举行电脑节,今年电脑节有一个新的趣味比赛项目叫做闯迷宫。

sun的室友在帮电脑节设计迷宫,所以室友就请sun帮忙计算下走出迷宫的最少步数。

知道了最少步数就可以辅助控制比赛难度以及去掉一些没有路径到达终点的map。

比赛规则是:从原点(0,0)开始走到终点(n-1,n-1),只能上下左右4个方向走,只能在给定的矩阵里走。

运行时间限制:10 Sec
内存限制:128 MByte
输入:

输入有多组数据。



每组数据输入n(0<n<=100),然后输入n*n的0、1矩阵,0代表该格子没有障碍,为1表示有障碍物。

注意:如果输入中的原点和终点为1则这个迷宫是不可达的。

输出:

对每组输入输出该迷宫的最短步数,若不能到达则输出-1。

样例输入:
2
0 1
0 0
5
0 0 0 0 0
1 0 1 0 1
0 0 0 0 0
0 1 1 1 0
1 0 1 0 0
样例输出:
2
8

BFS实现版:

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

class Point{

	int x,y;
	public Point(int x,int y) {
		// TODO Auto-generated constructor stub
		this.x=x;
		this.y=y;

	}

}
public class Main {

	static final int unreachable=100000;     //代表从未走过
	static int dx[]={0,1,0,-1};              
	static int dy[]={1,0,-1,0};
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner in=new Scanner(System.in);
		while (in.hasNextInt()) {

			int n=in.nextInt();
			int m=n;
			int maze[][]=new int[n][n];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					maze[i][j]=in.nextInt();
				}
			}
			
			
			
			if (maze[0][0]==1||maze[n-1][n-1]==1) {
				System.out.println(-1);
				continue;
			}
			
			int distance[][]=new int[n][n];
			initDistance(distance);
			distance[0][0]=0;
			int dis=bfs(maze,distance,n);
			if (dis==unreachable) {
				System.out.println(-1);
			}else {
				System.out.println(dis);
			}
			

		}
	}
	private static int bfs(int[][] maze, int[][] distance, int n) {
		// TODO Auto-generated method stub
		
		Queue<Point> q=new LinkedList<Point>();
		q.offer(new Point(0, 0));
		
		while (!q.isEmpty()) {
			Point front=q.poll();
			if (front.x==n-1&&front.y==n-1) {
				break;
			}
			
			for (int i = 0; i < 4; i++) {     //上下左右
				int px=front.x+dx[i];
				int py=front.y+dy[i];
				
				if (px>=0&&px<n&&py>=0&&py<n&&maze[px][py]!=1&&distance[px][py]==unreachable) {
					q.add(new Point(px, py));
					distance[px][py]=distance[front.x][front.y]+1;
				}
			}
		}
		return distance[n-1][n-1];
	}
	private static void initDistance(int[][] distance) {
		// TODO Auto-generated method stub
		for (int i = 0; i < distance.length; i++) {
			for (int j = 0; j < distance.length; j++) {
				distance[i][j]=unreachable;
			}
		}
		
	}

}

测试结果:



下面再给出DFS版本的解法

import java.util.Scanner;
import java.util.Stack;

class point{

	int x,y;
	public point(int x,int y) {
		// TODO Auto-generated constructor stub
		this.x=x;
		this.y=y;
	}

}
public class DFSMaze {
	static final int unreachable=100000;
	static int dx[]={0,1,0,-1};
	static int dy[]={1,0,-1,0};
	static int steps=-1;
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Scanner in=new Scanner(System.in);
		while (in.hasNextInt()) {
			
			int n=in.nextInt();
			int m=n;
			int maze[][]=new int[n][n];
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					maze[i][j]=in.nextInt();
				}
			}
			
			if (maze[0][0]==1||maze[n-1][n-1]==1) {
				System.out.println(-1);
				continue;
			}
			boolean visit[][]=new boolean[n][n];
			
			Stack<point> stack=new Stack<point>();
			int dis=dfs (maze,n,stack,visit);
			
			System.out.println(dis);
			
		}
	}
	private static int dfs(int[][] maze, int n, Stack<point> stack, boolean[][] visit) {
		// TODO Auto-generated method stub
		
		 recursive(maze,n,stack,0,0,visit);
		 return steps;
	}
	private static void recursive(int[][] maze, int n, Stack<point> stack, int x, int y, boolean[][] visit) {
		// TODO Auto-generated method stub
		stack.push(new point(x, y));
		if (x==n-1&&y==n-1) {
			System.out.println("Start.......");
			for (point p : stack) {
				System.out.println("("+p.x+","+p.y+")");
			}
			System.out.println("End........");
			steps=stack.size()-1;
			return;
		}
		visit[x][y]=true;
		for (int i = 0; i <4; i++) {
			int px=x+dx[i];
			int py=y+dy[i];
			if (px>=0&&px<n&&py>=0&&py<n&&maze[px][py]!=1&&visit[px][py]==false) {
				recursive(maze, n, stack, px, py,visit);
			}
		}
		stack.pop();
		visit[x][y]=false;
		
	}

}

测试结果:



//以下通用版,S代表起始点,G代表出口

实现代码:

import java.util.LinkedList;  
import java.util.Queue;  
import java.util.concurrent.ConcurrentLinkedQueue;  
  
/** 
 * Created by yangjianzhou on 2014/8/18 21:36. 
 * TODO :给定一个大小为N*M的迷宫,迷宫由通道和墙壁组成,每一步可以向邻接的上下左右四 
 * 格的通道移动。求从起点到终点所需的最小步数。 
 */  
public class Maze {  
  
    private static final int INF = 100000;  // 表示没有走过
    private static final int N = 10;  
    private static final int M = 10;  
    private static char[][] mazeMatrix = {  
            {'#', 'S', '#', '#', '#', '#', '#', '#', 'o', '#'},  
            {'o', 'o', 'o', 'o', 'o', 'o', '#', 'o', 'o', '#'},  
            {'o', '#', 'o', '#', '#', 'o', '#', '#', 'o', '#'},  
            {'o', '#', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o'},  
            {'#', '#', 'o', '#', '#', 'o', '#', '#', '#', '#'},  
            {'o', 'o', 'o', 'o', '#', 'o', 'o', 'o', 'o', '#'},  
            {'#', '#', '#', '#', '#', '#', '#', '#', 'o', '#'},  
            {'o', 'o', 'o', '#', 'o', 'o', 'o', 'o', 'o', 'o'},  
            {'o', '#', '#', '#', '#', 'o', '#', '#', '#', 'o'},  
            {'o', 'o', 'o', 'o', '#', 'o', 'o', 'o', 'G', '#'}  
    };  
    ;  
    private static int xs = 0;  
    private static int ys = 1;  
    private static int xe = 9;  
    private static int ye = 8;  
    private static int[][] distance = new int[N][M];  
  
    private static int[] xd = {1, 0, -1, 0};  
    private static int[] yd = {0, 1, 0, -1};  
  
    public static void main(String[] args) {  
        initDistance();  
        Maze maze = new Maze();  
        int dis = maze.bfs();  
        System.out.println("shortest length is : " + dis);  
       printDistance();  
    }  
  
    private int bfs() {  
        Queue<Point> que = new ConcurrentLinkedQueue<Point>();  
        que.add(new Point(xs, ys));  
        distance[xs][ys] = 0;  
        while (que.size() > 0) {  
            Point point = que.poll();  
            if (point.getX() == xe && point.getY() == ye) {  
                break;  
            }  
            for (int i = 0; i < 4; i++) {  
                int xp = point.getX() + xd[i];  
                int yp = point.getY() + yd[i];  
                if (0 <= xp && xp < N && 0 <= yp && yp < M && mazeMatrix[xp][yp] != '#' && distance[xp][yp] == INF) {  
                    que.add(new Point(xp, yp));  
                    distance[xp][yp] = distance[point.getX()][point.getY()] + 1;  
                }  
            }  
        }  
        return distance[xe][ye];  
    }  
  
    private static void initDistance() {  
        for (int i = 0; i < N; i++) {  
            for (int j = 0; j < M; j++) {  
                distance[i][j] = INF;  
            }  
        }  
    }  
  
    private static void printDistance() {  
        for (int i = 0; i < N; i++) {  
            System.out.println();  
            for (int j = 0; j < M; j++) {  
                System.out.print("\t\t" + distance[i][j]);  
            }  
        }  
    }  
  
    class Point {  
        int x;  
        int y;  
  
        public Point(int x, int y) {  
            this.x = x;  
            this.y = y;  
        }  
  
        public int getX() {  
            return x;  
        }  
  
        public int getY() {  
            return y;  
        }  
  
        public void setX(int x) {  
            this.x = x;  
        }  
  
        public void setY(int y) {  
            this.y = y;  
        }  
    }  
}  

测试结果:


动态规划是一种解决复杂问题的算法思想,它将原问题分解为多个子问题,并通过保存子问题的解来避免重复计算,从而实现高效的求解。在Python中,动态规划可以用来解决迷宫问题。 迷宫问题是指在一个迷宫中找到从起点到终点的路径。在动态规划的思想下,可以将迷宫看作一个二维的网格,其中每个网格可以是墙壁或者可以通过的空地。通过定义状态和状态转移方程,可以利用动态规划算法来找到最短路径或者所有可能的路径。 具体地说,可以使用一个二维数组来表示迷宫,其中每个元素代表一个网格的状态。然后,通过定义初始状态、状态转移方程和边界条件,可以逐步计算出所有网格的最优解,最终得到从起点到终点的最短路径或者所有可能的路径。 在解决迷宫问题时,可以利用递归或者迭代的方式进行求解。递归方式可以通过定义递归函数来实现,每次递归调用时,根据当前位置和当前状态,判断是否继续向下一步前进,并更新状态。迭代方式则可以使用动态规划的思想,通过迭代更新网格的状态,直到达到终点。 参考资料中提供了一份关于动态规划迷宫问题的python代码,你可以通过阅读该代码来了解具体的实现方法。同时,你也可以通过搜索其他相关资料来深入学习和了解动态规划在解决迷宫问题中的应用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [动态规划(DP)的整理-Python描述](https://blog.csdn.net/MrLevo520/article/details/75676160)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Python解法华为OJ-迷宫问题](https://blog.csdn.net/qq_39802810/article/details/115522203)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值