华为oj--迷宫问题

时间:2021-12-16 18:53:43
 

定义一个二维数组N*M(其中2<=N<=10;2<=M<=10),如5 × 5数组下所示: 

int maze[5][5] = {

        0, 1, 0, 0, 0,

        0, 1, 0, 1, 0,

        0, 0, 0, 0, 0,

        0, 1, 1, 1, 0,

        0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为[0,0],既第一空格是可以走的路。

Input

一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0

0 1 0 1 0

0 0 0 0 0

0 1 1 1 0

0 0 0 1 0

Sample Output

(0, 0)

(1, 0)

(2, 0)

(2, 1)

(2, 2)

(2, 3)

(2, 4)

(3, 4)

(4, 4)

遇到本题,本打算将上下左右四个方向都进行递归处理,但没有处理好,继而思考既然只有一条通路,那么就只处理向右和向下两个方向,也算是偷懒了。源代码如下:

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

class Node{
	int x;
	int y;
	public Node(int x,int y){
		this.x=x;
		this.y=y;
	}
}
public class Main{
	static Stack<Node> stack=new Stack<Node>();
	public static void main(String[] args) {
		Stack<String> result=new Stack<String>();
		Scanner scanner=new Scanner(System.in);
		int n=scanner.nextInt();
		int m=scanner.nextInt();
		int[][] map=new int[n][m];
		boolean[][] visited=new boolean[n][m];
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				map[i][j]=scanner.nextInt();
		getPath(map,visited,n,m,0,0);
		while(!stack.isEmpty()){
			Node temp=stack.pop();
			result.push("("+temp.x+","+temp.y+")");
		}
		while(!result.isEmpty()){
			System.out.println(result.pop());
		}
	}

	public static void getPath(int[][] map, boolean[][] visited,int n,int m,int i,int j) {
		if(i<0||j<0||i>n||j>n){
			return;
		}
		visited[i][j]=true;
		boolean flag=false;
		Node node=new Node(i,j);
		stack.push(node);
		if(i==n-1&&j==n-1){
			return;
		}
//		if(i-1>=0){
//			if(map[i-1][j]==0){
//				getPath(map,visited,n,i-1,j);
//			}
//		}
		if(i+1<n){   //下
			if(map[i+1][j]==0&&!visited[i+1][j]){
				flag=true;
				getPath(map,visited,n,m,i+1,j);
			}
		}
//		if(j-1>=0){
//			if(map[i][j-1]==0){
//				getPath(map,visited,n,i,j-1);
//			}
//		}
		if(j+1<m){  //右
			if(map[i][j+1]==0&&!visited[i][j+1]){
				flag=true;
				getPath(map,visited,n,m,i,j+1);
			}
		}
		if(flag==false){   //该点的右、下方向都走不通
		   stack.pop();  //弹出该点
		   Node temp=stack.pop();//弹出该点的前一点
		   visited[temp.x][temp.y]=false;//将该点的前一点设为未访问过
		   getPath(map,visited,n,m,temp.x,temp.y);//重新处理该点的上一点
		}
	}
}