华为机试 迷宫最短路径

闯迷宫
 
描述:

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;  
        }  
    }  
}  

测试结果:


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值