📜  迷宫中的老鼠的变体:允许多步或跳跃

📅  最后修改于: 2021-09-17 07:38:13             🧑  作者: Mango

迷宫中老鼠的变种。
给你一个N * N二维矩阵形状的迷宫(我们称之为 M),左上角的单元格中有一只老鼠,即M[0][0]右下角的单元格中有一个逃生门即M[N-1][N-1] 。从每个单元格M[i][j] (0 ≤ i ≤ N-1, 0 ≤ j ≤ N-1) 大鼠可以向右移动多个步骤(例如:到 M[i][j+ s ]),或向下的步数(例如:到 M[i+ s][j]),其中最大步数(或 s 的最大值)可以是单元格M[i][j] 中的值] 。如果任何单元格包含0则这是一个死胡同例如:在下图中的第二张图片中, M[0][0]处的老鼠可以跳到一个单元格: M[0][1] , M[0][2] , M[1][0] ]M[2][0]

您必须以大小为N * N的矩阵的形式打印从 M[0][0] 到 M[N-1][N-1]的可能路径以便路径中的单元格具有值1和其他单元格的值为0 。对于上面的例子,一个这样的解决方案是:

这篇文章有针对这个问题的回溯解决方案
这里介绍了基于动态规划的解决方案。
例子:

方法:

  • false初始化一个布尔CRF[N][N] (可以从)矩阵。现在使CRF[N – 1][N – 1] = true因为可以从目的地到达目的地。
  • 现在,从maze[N – 1][N – 1]开始到maze[0][0]结束,根据是否有可能到达任何其他有效单元格更新CRF[][] 中的所有单元格(导致目的地)。
  • 当所有CRF[][]矩阵都已更新后,用于创建一个矩阵,该矩阵包含通向目的地的路径中的单元格处全为1且其他单元格为0的矩阵。
  • 最后打印这个新创建的矩阵。
  • 如果无法到达目的地,则打印No path exists

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
#define MAX 50
 
// Function to check whether the path exists
bool hasPath(int maze[][MAX], int sol[][MAX],
                                     int N)
{
 
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            sol[i][j] = 0;
 
    // Declaring and initializing CRF
    // (can reach from) matrix
    bool** CRF = new bool*[N];
    for (int i = 0; i < N; i++)
        CRF[i] = new bool[N];
 
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            CRF[i][j] = false;
    CRF[N - 1][N - 1] = true;
 
    // Using the DP to fill CRF matrix
    // in correct order
    for (int k = N - 1; k >= 0; k--) {
        for (int j = k; j >= 0; j--) {
 
            if (!(k == N - 1 && j == N - 1)) {
 
                // If it is possible to get
                // to a valid location from
                // cell maze[k][j]
                for (int a = 0; a <= maze[k][j]; a++) {
                    if ((j + a < N && CRF[k][j + a] == true)
                        || (k + a < N && CRF[k + a][j] == true)) {
                        CRF[k][j] = true;
                        break;
                    }
                }
 
                // If it is possible to get to
                // a valid location from cell
                // maze[j][k]
                for (int a = 0; a <= maze[j][k]; a++) {
                    if ((k + a < N && CRF[j][k + a] == true)
                        || (j + a < N && CRF[j + a][k] == true)) {
                        CRF[j][k] = true;
                        break;
                    }
                }
            }
        }
    }
 
    // If CRF[0][0] is false it means we cannot reach
    // the end of the maze at all
    if (CRF[0][0] == false)
        return false;
 
    // Filling the solution matrix using CRF
    int i = 0, j = 0;
    while (!(i == N - 1 && j == N - 1)) {
        sol[i][j] = 1;
        if (maze[i][j] > 0)
 
            // Get to a valid location from
            // the current cell
            for (int a = 1; a <= maze[i][j]; a++) {
                if ((j + a < N && CRF[i][j + a] == true)) {
                    j = j + a;
                    break;
                }
                else if ((i + a < N && CRF[i + a][j] == true)) {
                    i = i + a;
                    break;
                }
            }
    }
    sol[N - 1][N - 1] = 1;
 
    return true;
}
 
// Utility function to print the contents
// of a 2-D array
void printMatrix(int sol[][MAX], int N)
{
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++)
            cout << sol[i][j] << " ";
        cout << "\n";
    }
}
 
// Driver code
int main()
{
 
    int maze[][MAX] = { { 2, 2, 1, 1, 0 },
                        { 0, 0, 3, 0, 0 },
                        { 1, 0, 0, 0, 0 },
                        { 0, 0, 2, 0, 1 },
                        { 0, 0, 3, 0, 0 } };
    int N = sizeof(maze) / sizeof(maze[0]);
    int sol[N][MAX];
 
    // If path exists
    if (hasPath(maze, sol, N))
 
        // Print the path
        printMatrix(sol, N);
    else
        cout << "No path exists";
 
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
static int MAX = 50;
 
// Function to check whether the path exists
static boolean hasPath(int maze[][],
                       int sol[][], int N)
{
    for (int i = 0; i < N; i++)
        for (int j = 0; j < N; j++)
            sol[i][j] = 0;
 
    // Declaring and initializing CRF
    // (can reach from) matrix
    boolean [][]CRF = new boolean[N][N];
 
    CRF[N - 1][N - 1] = true;
 
    // Using the DP to fill CRF matrix
    // in correct order
    for (int k = N - 1; k >= 0; k--)
    {
        for (int j = k; j >= 0; j--)
        {
 
            if (!(k == N - 1 && j == N - 1))
            {
 
                // If it is possible to get
                // to a valid location from
                // cell maze[k][j]
                for (int a = 0; a <= maze[k][j]; a++)
                {
                    if ((j + a < N && CRF[k][j + a] == true) ||
                        (k + a < N && CRF[k + a][j] == true))
                    {
                        CRF[k][j] = true;
                        break;
                    }
                }
 
                // If it is possible to get to
                // a valid location from cell
                // maze[j][k]
                for (int a = 0; a <= maze[j][k]; a++)
                {
                    if ((k + a < N && CRF[j][k + a] == true) ||
                        (j + a < N && CRF[j + a][k] == true))
                    {
                        CRF[j][k] = true;
                        break;
                    }
                }
            }
        }
    }
 
    // If CRF[0][0] is false it means we cannot reach
    // the end of the maze at all
    if (CRF[0][0] == false)
        return false;
 
    // Filling the solution matrix using CRF
    int i = 0, j = 0;
    while (!(i == N - 1 && j == N - 1))
    {
        sol[i][j] = 1;
        if (maze[i][j] > 0)
 
            // Get to a valid location from
            // the current cell
            for (int a = 1; a <= maze[i][j]; a++)
            {
                if ((j + a < N && CRF[i][j + a] == true))
                {
                    j = j + a;
                    break;
                }
                else if ((i + a < N && CRF[i + a][j] == true))
                {
                    i = i + a;
                    break;
                }
            }
    }
    sol[N - 1][N - 1] = 1;
 
    return true;
}
 
// Utility function to print the contents
// of a 2-D array
static void printMatrix(int sol[][], int N)
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            System.out.print(sol[i][j] + " ");
        System.out.println();
    }
}
 
// Driver code
public static void main(String[] args)
{
    int maze[][] = {{ 2, 2, 1, 1, 0 },
                    { 0, 0, 3, 0, 0 },
                    { 1, 0, 0, 0, 0 },
                    { 0, 0, 2, 0, 1 },
                    { 0, 0, 3, 0, 0 }};
    int N = maze.length;
    int [][]sol = new int [N][MAX];
 
    // If path exists
    if (hasPath(maze, sol, N))
 
        // Print the path
        printMatrix(sol, N);
    else
        System.out.println("No path exists");
    }
}
 
// This code is contributed by Princi Singh


C#
// C# implementation of the approach
using System;
 
class GFG
{
static int MAX = 50;
 
// Function to check whether the path exists
static Boolean hasPath(int [,]maze,
                       int [,]sol, int N)
{
    int i, j, k;
    for (i = 0; i < N; i++)
        for (j = 0; j < N; j++)
            sol[i, j] = 0;
 
    // Declaring and initializing CRF
    // (can reach from) matrix
    Boolean [,]CRF = new Boolean[N, N];
 
    CRF[N - 1, N - 1] = true;
 
    // Using the DP to fill CRF matrix
    // in correct order
    for (k = N - 1; k >= 0; k--)
    {
        for (j = k; j >= 0; j--)
        {
            if (!(k == N - 1 && j == N - 1))
            {
 
                // If it is possible to get
                // to a valid location from
                // cell maze[k,j]
                for (int a = 0; a <= maze[k, j]; a++)
                {
                    if ((j + a < N && CRF[k, j + a] == true) ||
                        (k + a < N && CRF[k + a, j] == true))
                    {
                        CRF[k, j] = true;
                        break;
                    }
                }
 
                // If it is possible to get to
                // a valid location from cell
                // maze[j,k]
                for (int a = 0; a <= maze[j, k]; a++)
                {
                    if ((k + a < N && CRF[j, k + a] == true) ||
                        (j + a < N && CRF[j + a, k] == true))
                    {
                        CRF[j, k] = true;
                        break;
                    }
                }
            }
        }
    }
 
    // If CRF[0,0] is false it means we cannot
    // reach the end of the maze at all
    if (CRF[0, 0] == false)
        return false;
 
    // Filling the solution matrix using CRF
    i = 0; j = 0;
    while (!(i == N - 1 && j == N - 1))
    {
        sol[i, j] = 1;
        if (maze[i, j] > 0)
 
            // Get to a valid location from
            // the current cell
            for (int a = 1; a <= maze[i, j]; a++)
            {
                if ((j + a < N &&
                     CRF[i, j + a] == true))
                {
                    j = j + a;
                    break;
                }
                else if ((i + a < N &&
                          CRF[i + a, j] == true))
                {
                    i = i + a;
                    break;
                }
            }
    }
    sol[N - 1, N - 1] = 1;
 
    return true;
}
 
// Utility function to print the contents
// of a 2-D array
static void printMatrix(int [,]sol, int N)
{
    for (int i = 0; i < N; i++)
    {
        for (int j = 0; j < N; j++)
            Console.Write(sol[i, j] + " ");
        Console.WriteLine();
    }
}
 
// Driver code
public static void Main(String[] args)
{
    int [,]maze = {{ 2, 2, 1, 1, 0 },
                   { 0, 0, 3, 0, 0 },
                   { 1, 0, 0, 0, 0 },
                   { 0, 0, 2, 0, 1 },
                   { 0, 0, 3, 0, 0 }};
    int N = maze.GetLength(0);
    int [,]sol = new int [N, MAX];
 
    // If path exists
    if (hasPath(maze, sol, N))
 
        // Print the path
        printMatrix(sol, N);
    else
        Console.WriteLine("No path exists");
    }
}
 
// This code is contributed by Rajput-Ji


Javascript


输出:
1 1 1 0 0 
0 0 1 0 0 
0 0 0 0 0 
0 0 1 0 0 
0 0 1 0 1

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程