AcWing - grid maze (a little different maze problem)

4943. Square Maze - AcWing Question Bank

 1. Topic

Given a square matrix with n rows and m columns.

Rows are numbered 1∼n from top to bottom, and columns are numbered 1∼m from left to right.

The square at row i and column j is denoted as (i,j).

Squares in the matrix are either clearings (  . denoted by y ) or traps (  # denoted by y ).

Initially, you are on square (x₁,y₁) and you need to go to square (x₂,y₂).

For each move , you can choose one of the four directions up, down, left, and right, and move 1∼k steps along that direction.

Moving from one square to an adjacent square counts as one step.

However, you have to ensure that you cannot get out of the matrix or enter the trap square during your movement.

Please calculate the minimum number of moves required to move from square (x₁,y₁) to square (x₂,y₂) .

Make sure that squares (x₁,y₁) and squares (x₂,y₂) are empty spaces.

Square (x₁,y₁) and square (x₂,y₂) may be the same square.

Note: Pay attention to the difference between the number of moves and the number of steps in this question.

input format

The first line contains three integers n,m,k.

The next n lines, each line contains m characters, where the jth character in the i-th line is either,  .indicating that the square (i, j) is an open space; or yes,  #indicating that the square (i, j) is a trap.

The last line contains four integers x₁,y₁,x₂,y₂.

output format

An integer representing the minimum number of moves required .

Output if it is not possible to move from cell (x₁,y₁) to cell (x₂,y₂)  -1.

data range

The first 6 test points satisfy 1≤n, m≤10.
All test points satisfy 1≤n,m,k≤1000, 1≤x₁,x₂≤n, 1≤y₂,y₂≤m.

Input sample 1:

3 4 4
....
###.
....
1 1 3 1

Output sample 1:

3

Input sample 2:

3 4 1
....
###.
....
1 1 3 1

Output sample 2:

8

Input sample 3:

2 2 1
.#
#.
1 1 2 2

Output sample 3:

-1

2. Topic Interpretation

Walk the Maze

Niuke.com's question is normal, and it is common to solve the maze problem with the shortest number of steps, and this question adds a condition: each time you move , you can choose one of the four directions of up, down, left, and right, and move along that direction. Move 1∼k steps . This is called a move.

We use BFS to normally answer this question. The time complexity is O(nmk) and the maximum is 10⁹, which will time out.


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

public class Main {
    static int n,m,k,x1,x2,y1,y2;
    static char[][] ch;
    static int[][] move ={
   
   {0,1},{0,-1},{1,0},{-1,0}};//四个方向,偏移量
    static int inf=0x3f3f3f3f;//初始化移动次数
    static int[][] ans;//记录移动次数
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        k=sc.nextInt();
        ch =new char[n][];
        ans =new int[n][m];
        for(int i=0;i<n;i++){
            ch[i]=sc.next().toCharArray();
        }
        x1=sc.nextInt()-1;
        y1=sc.nextInt()-1;
        x2=sc.nextInt()-1;
        y2=sc.nextInt()-1;
        for(int i=0;i<n;i++){//初始化移动次数
            Arrays.fill(ans[i],inf);
        }
        System.out.println(bfs());
    }
    public static int bfs(){
        ans[x1][y1]=0;
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{x1,y1,0});
        while(!q.isEmpty()){
            int[] a =q.poll();
            for(int[] mo :move){//四个方向
                for(int i=1;i<=k;i++){//移动一次:移动1-k步
                    int x=a[0]+mo[0]*i,y=a[1]+mo[1]*i;
                    if(x<0||x==n||y<0||y==m||ch[x][y]=='#'){//不能出去,不能跨越陷阱
                        break;
                    }
                    if(ans[x][y]>a[2]+1){//修改移动次数
                        ans[x][y]=a[2]+1;
                        q.add(new int[]{x,y,a[2]+1});
                    }
                }
            }
        }
        //走完整个地图,判断目的地是否可以走到
        return ans[x2][y2]==inf?-1:ans[x2][y2];
    }
}

We need to optimize the code, see the picture below:

 

So we should update to the grid and find that it is not optimal, so we should stop. In this way, the time complexity degenerates to O(nm)

Need to add new at the judgment condition: ans[x][y]<a[2]+1

3. Code


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

public class Main {
    static int n,m,k,x1,x2,y1,y2;
    static char[][] ch;
    static int[][] move ={
   
   {0,1},{0,-1},{1,0},{-1,0}};//四个方向,偏移量
    static int inf=0x3f3f3f3f;//初始化移动次数
    static int[][] ans;//记录移动次数
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
        n=sc.nextInt();
        m=sc.nextInt();
        k=sc.nextInt();
        ch =new char[n][];
        ans =new int[n][m];
        for(int i=0;i<n;i++){
            ch[i]=sc.next().toCharArray();
        }
        x1=sc.nextInt()-1;
        y1=sc.nextInt()-1;
        x2=sc.nextInt()-1;
        y2=sc.nextInt()-1;
        for(int i=0;i<n;i++){//初始化移动次数
            Arrays.fill(ans[i],inf);
        }
        System.out.println(bfs());
    }
    public static int bfs(){
        ans[x1][y1]=0;
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{x1,y1,0});
        while(!q.isEmpty()){
            int[] a =q.poll();
            for(int[] mo :move){//四个方向
                for(int i=1;i<=k;i++){//移动一次:移动1-k步
                    int x=a[0]+mo[0]*i,y=a[1]+mo[1]*i;
                    //不能出去,不能跨越陷阱,还有更新到格子发现不是最优,就应该停止
                    if(x<0||x==n||y<0||y==m||ch[x][y]=='#'||ans[x][y]<a[2]+1){
                        break;
                    }
                    if(ans[x][y]>a[2]+1){//修改移动次数
                        ans[x][y]=a[2]+1;
                        q.add(new int[]{x,y,a[2]+1});
                    }
                }
            }
        }
        //走完整个地图,判断目的地是否可以走到
        return ans[x2][y2]==inf?-1:ans[x2][y2];
    }
}

 

Guess you like

Origin blog.csdn.net/m0_63951142/article/details/130516880