The shortest path in the maze [Java implementation]

Question description

There is a maze of size n∗m, where 1 represents an impassable wall and 0 represents a flat ground. Each movement can only move one space up, down, left, and right, and can only be moved on flat ground. Assume that the coordinates of the upper left corner are (1,1), the number of rows increases in the direction of x growth, and the number of columns increases in the direction of y growth direction, find the path with the minimum number of steps from the upper left corner of the maze to the lower right corner.

Enter description

Two integers in the first linen、m(2≤n≤100,2≤m≤100) represent the number of rows and columns of the maze respectively;

The nextn lines contain m integers each (the values ​​are 0 or 1), indicating a maze.

Output description

Starting from the coordinates of the upper left corner, output several lines (two integers per line, representing one coordinate) until the coordinates of the lower right corner.

The data guarantees that the path with the minimum number of steps exists and is unique.

Sample

enter

3 3
0 1 0
0 0 0
0 1 0

output

1 1
2 1
2 2
2 3
3 3

explain

Assume that the coordinates of the upper left corner are(1,1), the number of rows increases in the direction of x, and the number of columns increases in the direction of < a i=3>The direction of growth. y

The path with the minimum number of steps from the upper left corner to the lower right corner can be obtained as:(1,1)=>(2,1)=>(2,2)=>(2,3)=>(3,3)

Idea analysis

  • Regarding the problem of the shortest path in the maze, the idea of ​​​​breadth-first search is generally adopted, because the "sweeping army" form of breadth search ensures that the distance when the current point reaches the point around it must be the smallest, and so on, so that the search continues to reach the goal. The distance between points must also be minimum.
  • However, the difficulty of this question is that we are required to output the specific path of the shortest distance. If it is a depth-first search, recursion can be used to output the path very well, but breadth-first is not achieved by recursion.So how to ensure that we can still find the "turn back" (that is, how to know where to start from that point) after reaching the target location is the problem we need to solve.
  • A good way is to create a two-dimensional array with the same dimensions as the mapPair prePosition[n][m], wherePair is our custom class and its storage point The coordinate information of the prePosition array stores the coordinate information of the previous point to the current point, such as prePosition[i][j]=new Pair(x,y) representing breadth-first search (x,y)的下一个点是(i,j), the previous coordinate of the initial (0,0) is (-1,-1).
  • We go from the starting point to the end point through ordinary breadth-first search. During this process, we pay attention to recording the previous coordinates of the current point. When we get to the last point, we only need to use simple recursion to locate based on the "clues" left before. Go to the starting position and then print.

Code

package homework;

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

public class Main {
    
    

	public static void main(String[] args) {
    
    
		Scanner scanner = new Scanner(System.in);
		int n = scanner.nextInt();
		int m = scanner.nextInt();
		int arr[][] = new int[n][m];
		for (int i = 0; i < n; i++) {
    
    
			for (int j = 0; j < m; j++) {
    
    
				arr[i][j] = scanner.nextInt();
			}
		}
		BFS(arr, n, m);
	}

	public static void BFS(int arr[][], int n, int m) {
    
    
		LinkedList<Pair> queue = new LinkedList<Pair>();
		// 广度遍历时,(x,y)下标对应的上一个坐标
		Pair prePosition[][] = new Pair[n][m];
		Pair pair = new Pair(0, 0);
		prePosition[0][0] = new Pair(-1, -1);
		queue.addLast(pair);
		arr[0][0] = 1;
		int dx[] = {
    
     0, 0, 1, -1 };
		int dy[] = {
    
     1, -1, 0, 0 };
		while (!queue.isEmpty()) {
    
    
			int size = queue.size();
			for (int i = 0; i < size; i++) {
    
    
				Pair poll = queue.poll();
				if (poll.row == n - 1 && poll.cols == m - 1) {
    
    
					printCoord(prePosition, n - 1, m - 1);
					return;
				} else {
    
    
					Pair pre = new Pair(poll.row, poll.cols);
					for (int j = 0; j < 4; j++) {
    
    
						int nextX = poll.row + dx[j];
						int nextY = poll.cols + dy[j];
						if (canVisited(arr, n, m, nextX, nextY)) {
    
    
							queue.addLast(new Pair(nextX, nextY));
							prePosition[nextX][nextY] = pre;
							arr[nextX][nextY] = 1;
						}
					}
				}
			}
		}

	}

	static void printCoord(Pair prePosition[][], int row, int cols) {
    
    
		if (row != -1 && cols != -1) {
    
    
			Pair pair = prePosition[row][cols];
			printCoord(prePosition, pair.row, pair.cols);
			System.out.println((row + 1) + " " + (cols + 1));
		}
	}

	public static boolean canVisited(int arr[][], int n, int m, int x, int y) {
    
    
		return x >= 0 && x < n && y >= 0 && y < m && arr[x][y] == 0;
	}

}

class Pair {
    
    
	int row;
	int cols;

	public Pair(int x, int y) {
    
    
		this.row = x;
		this.cols = y;
	}

}

image-20230210135137794

Guess you like

Origin blog.csdn.net/weixin_45488428/article/details/128968857