迷宫中的老鼠变种。
给您一个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 。对于上面的示例,这样的解决方案是:
本文中有针对此问题的回溯解决方案。
这里提出了一种基于动态编程的解决方案。
例子:
Input: mat[][] = {
{3, 0, 0, 2, 1},
{0, 0, 0, 0, 2},
{0, 1, 0, 1, 0},
{1, 0, 0, 1, 1},
{3, 0, 0, 1, 1} }
Output:
1 0 0 1 1
0 0 0 0 1
0 0 0 0 0
0 0 0 0 1
0 0 0 0 1
Input: mat[][] = { {0, 0}, {0, 1} }
Output: No path exists
方法:
- 用false初始化布尔CRF [N] [N] (可以到达)矩阵。现在使CRF [N – 1] [N – 1] = true,因为可以从目标位置到达目标位置。
- 现在,从迷宫[N – 1] [N – 1]开始,到迷宫[0] [0]结束,根据是否有可能到达任何其他有效像元,更新CRF [] []中的所有像元(导致目的地)。
- 更新所有CRF [] []矩阵后,可使用创建一个矩阵,该矩阵在通向目标的路径中的单元格中包含全1 ,而其他单元格则为0 。
- 最后打印此新创建的矩阵。
- 如果无法到达目的地,则打印不存在路径。
下面是上述方法的实现:
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
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