给定一个包含正数的方形迷宫,找到从角单元(四个极端中的任意一个)到中间单元的所有路径。我们可以从一个单元格向北,向东,向西和向南四个方向精确地移动n步,其中n是该单元格的值,
我们可以从单元格mat [i] [j]移到mat [i + n] [j],mat [in] [j],mat [i] [j + n]和mat [i] [jn]其中n是mat [i] [j]的值。
例子
Input: 9 x 9 maze
[ 3, 5, 4, 4, 7, 3, 4, 6, 3 ]
[ 6, 7, 5, 6, 6, 2, 6, 6, 2 ]
[ 3, 3, 4, 3, 2, 5, 4, 7, 2 ]
[ 6, 5, 5, 1, 2, 3, 6, 5, 6 ]
[ 3, 3, 4, 3, 0, 1, 4, 3, 4 ]
[ 3, 5, 4, 3, 2, 2, 3, 3, 5 ]
[ 3, 5, 4, 3, 2, 6, 4, 4, 3 ]
[ 3, 5, 1, 3, 7, 5, 3, 6, 4 ]
[ 6, 2, 4, 3, 4, 5, 4, 5, 1 ]
Output:
(0, 0) -> (0, 3) -> (0, 7) ->
(6, 7) -> (6, 3) -> (3, 3) ->
(3, 4) -> (5, 4) -> (5, 2) ->
(1, 2) -> (1, 7) -> (7, 7) ->
(7, 1) -> (2, 1) -> (2, 4) ->
(4, 4) -> MID
这个想法是使用回溯。我们从迷宫的每个角单元开始,然后递归检查它是否导致了解。以下是回溯算法–
如果到达目的地
- 打印路径
别的
- 将当前单元格标记为已访问并将其添加到路径数组。
- 沿所有允许的4个方向前进,并递归检查其中是否有任何解决方法。
- 如果以上解决方案均无效,则将该单元标记为未访问,并将其从路径数组中删除。
下面是上述方法的实现:
C++
// C++ program to find a path from corner cell to
// middle cell in maze containing positive numbers
#include
using namespace std;
// Rows and columns in given maze
#define N 9
// check whether given cell is a valid cell or not.
bool isValid(set > visited,
pair pt)
{
// check if cell is not visited yet to
// avoid cycles (infinite loop) and its
// row and column number is in range
return (pt.first >= 0) && (pt.first < N) &&
(pt.second >= 0) && (pt.second < N) &&
(visited.find(pt) == visited.end());
}
// Function to print path from source to middle coordinate
void printPath(list > path)
{
for (auto it = path.begin(); it != path.end(); it++)
cout << "(" << it->first << ", "
<< it->second << ") -> ";
cout << "MID" << endl << endl;
}
// For searching in all 4 direction
int row[] = {-1, 1, 0, 0};
int col[] = { 0, 0, -1, 1};
// Cordinates of 4 corners of matrix
int _row[] = { 0, 0, N-1, N-1};
int _col[] = { 0, N-1, 0, N-1};
void findPathInMazeUtil(int maze[N][N],
list > &path,
set > &visited,
pair &curr)
{
// If we have reached the destination cell.
// print the complete path
if (curr.first == N / 2 && curr.second == N / 2)
{
printPath(path);
return;
}
// consider each direction
for (int i = 0; i < 4; ++i)
{
// get value of current cell
int n = maze[curr.first][curr.second];
// We can move N cells in either of 4 directions
int x = curr.first + row[i]*n;
int y = curr.second + col[i]*n;
// Constructs a pair object with its first element
// set to x and its second element set to y
pair next = make_pair(x, y);
// if valid pair
if (isValid(visited, next))
{
// mark cell as visited
visited.insert(next);
// add cell to current path
path.push_back(next);
// recuse for next cell
findPathInMazeUtil(maze, path, visited, next);
// backtrack
path.pop_back();
// remove cell from current path
visited.erase(next);
}
}
}
// Function to find a path from corner cell to
// middle cell in maze contaning positive numbers
void findPathInMaze(int maze[N][N])
{
// list to store complete path
// from source to destination
list > path;
// to store cells already visisted in current path
set > visited;
// Consider each corners as the starting
// point and search in maze
for (int i = 0; i < 4; ++i)
{
int x = _row[i];
int y = _col[i];
// Constructs a pair object
pair pt = make_pair(x, y);
// mark cell as visited
visited.insert(pt);
// add cell to current path
path.push_back(pt);
findPathInMazeUtil(maze, path, visited, pt);
// backtrack
path.pop_back();
// remove cell from current path
visited.erase(pt);
}
}
int main()
{
int maze[N][N] =
{
{ 3, 5, 4, 4, 7, 3, 4, 6, 3 },
{ 6, 7, 5, 6, 6, 2, 6, 6, 2 },
{ 3, 3, 4, 3, 2, 5, 4, 7, 2 },
{ 6, 5, 5, 1, 2, 3, 6, 5, 6 },
{ 3, 3, 4, 3, 0, 1, 4, 3, 4 },
{ 3, 5, 4, 3, 2, 2, 3, 3, 5 },
{ 3, 5, 4, 3, 2, 6, 4, 4, 3 },
{ 3, 5, 1, 3, 7, 5, 3, 6, 4 },
{ 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
findPathInMaze(maze);
return 0;
}
Java
// Java program to find a path from corner cell to
// middle cell in maze containing positive numbers
import java.io.*;
class GFG {
public static void main (String[] args) {
// Creating the maze
int[][] maze = {
{ 3, 5, 4, 4, 7, 3, 4, 6, 3 },
{ 6, 7, 5, 6, 6, 2, 6, 6, 2 },
{ 3, 3, 4, 3, 2, 5, 4, 7, 2 },
{ 6, 5, 5, 1, 2, 3, 6, 5, 6 },
{ 3, 3, 4, 3, 0, 1, 4, 3, 4 },
{ 3, 5, 4, 3, 2, 2, 3, 3, 5 },
{ 3, 5, 4, 3, 2, 6, 4, 4, 3 },
{ 3, 5, 1, 3, 7, 5, 3, 6, 4 },
{ 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
// Calling the printPath function
printPath(maze,0,0,"");
}
public static void printPath(int[][] maze, int i, int j, String ans){
// If we reach the center cell
if (i == maze.length/2 && j==maze.length/2){
// Make the final answer, Print the
// final answer and Return
ans += "("+i+", "+j+") -> MID";
System.out.println(ans);
return;
}
// If the element at the current position
// in maze is 0, simply Return as it has
// been visited before.
if (maze[i][j]==0){
return;
}
// If element is non-zero, then note
// the element in variable 'k'
int k = maze[i][j];
// Mark the cell visited by making the
// element 0. Don't worry, the element
// is safe in 'k'
maze[i][j]=0;
// Make recursive calls in all 4
// directions pro-actively i.e. if the next
// cell lies in maze or not. Right call
if (j+k ");
}
// down call
if (i+k ");
}
// left call
if (j-k>0){
printPath(maze, i, j-k, ans+"("+i+", "+j+") -> ");
}
// up call
if (i-k>0){
printPath(maze, i-k, j, ans+"("+i+", "+j+") -> ");
}
// Unmark the visited cell by substituting
// its original value from 'k'
maze[i][j] = k;
}
}
Python3
# Python program to find a path from corner cell to
# middle cell in maze containing positive numbers
def printPath(maze, i, j, ans):
# If we reach the center cell
if (i == len(maze) // 2 and j == len(maze) // 2):
# Make the final answer, Prthe
# final answer and Return
ans += "(" + str(i) + ", " + str(j) + ") -> MID";
print(ans);
return;
# If the element at the current position
# in maze is 0, simply Return as it has
# been visited before.
if (maze[i][j] == 0):
return;
# If element is non-zero, then note
# the element in variable 'k'
k = maze[i][j];
# Mark the cell visited by making the
# element 0. Don't worry, the element
# is safe in 'k'
maze[i][j] = 0;
# Make recursive calls in all 4
# directions pro-actively i.e. if the next
# cell lies in maze or not. Right call
if (j + k < len(maze)):
printPath(maze, i, j + k, ans + "(" + str(i) + ", " + str(j) + ") -> ");
# down call
if (i + k < len(maze)):
printPath(maze, i + k, j, ans + "(" + str(i) + ", " + str(j) + ") -> ");
# left call
if (j - k > 0):
printPath(maze, i, j - k, ans + "(" + str(i) + ", " + str(j) + ") -> ");
# up call
if (i - k > 0):
printPath(maze, i - k, j, ans + "(" + str(i) + ", " + str(j) + ") -> ");
# Unmark the visited cell by substituting
# its original value from 'k'
maze[i][j] = k;
# Driver code
if __name__ == '__main__':
# Creating the maze
maze = [[ 3, 5, 4, 4, 7, 3, 4, 6, 3 ],[ 6, 7, 5, 6, 6, 2, 6, 6, 2 ],[ 3, 3, 4, 3, 2, 5, 4, 7, 2 ],
[ 6, 5, 5, 1, 2, 3, 6, 5, 6 ],[ 3, 3, 4, 3, 0, 1, 4, 3, 4 ],[ 3, 5, 4, 3, 2, 2, 3, 3, 5 ],
[ 3, 5, 4, 3, 2, 6, 4, 4, 3 ],[ 3, 5, 1, 3, 7, 5, 3, 6, 4 ],[ 6, 2, 4, 3, 4, 5, 4, 5, 1 ]] ;
# Calling the printPath function
printPath(maze, 0, 0, "");
# This code contributed by gauravrajput1
C#
// C# program to find a path from corner
// cell to middle cell in maze containing
// positive numbers
using System;
class GFG{
// Driver Code
public static void Main(String[] args)
{
// Creating the maze
int[,] maze = {
{ 3, 5, 4, 4, 7, 3, 4, 6, 3 },
{ 6, 7, 5, 6, 6, 2, 6, 6, 2 },
{ 3, 3, 4, 3, 2, 5, 4, 7, 2 },
{ 6, 5, 5, 1, 2, 3, 6, 5, 6 },
{ 3, 3, 4, 3, 0, 1, 4, 3, 4 },
{ 3, 5, 4, 3, 2, 2, 3, 3, 5 },
{ 3, 5, 4, 3, 2, 6, 4, 4, 3 },
{ 3, 5, 1, 3, 7, 5, 3, 6, 4 },
{ 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
// Calling the printPath function
printPath(maze, 0, 0, "");
}
public static void printPath(int[,] maze, int i,
int j, String ans)
{
// If we reach the center cell
if (i == maze.GetLength(0) / 2 &&
j == maze.GetLength(1) / 2)
{
// Make the readonly answer, Print the
// readonly answer and Return
ans += "(" + i + ", " + j + ") -> MID";
Console.WriteLine(ans);
return;
}
// If the element at the current position
// in maze is 0, simply Return as it has
// been visited before.
if (maze[i, j] == 0)
{
return;
}
// If element is non-zero, then note
// the element in variable 'k'
int k = maze[i, j];
// Mark the cell visited by making the
// element 0. Don't worry, the element
// is safe in 'k'
maze[i, j] = 0;
// Make recursive calls in all 4
// directions pro-actively i.e. if the next
// cell lies in maze or not. Right call
if (j + k < maze.GetLength(1))
{
printPath(maze, i, j + k,
ans + "(" + i +
", " + j + ") -> ");
}
// Down call
if (i + k < maze.GetLength(0))
{
printPath(maze, i + k, j,
ans + "(" + i +
", " + j + ") -> ");
}
// Left call
if (j - k > 0)
{
printPath(maze, i, j - k,
ans + "(" + i +
", " + j + ") -> ");
}
// Up call
if (i - k > 0)
{
printPath(maze, i - k, j,
ans + "(" + i +
", " + j + ") -> ");
}
// Unmark the visited cell by substituting
// its original value from 'k'
maze[i, j] = k;
}
}
// This code is contributed by gauravrajput1
输出 :
(0, 0) -> (0, 3) -> (0, 7) ->
(6, 7) -> (6, 3) -> (3, 3) ->
(3, 4) -> (5, 4) -> (5, 2) ->
(1, 2) -> (1, 7) -> (7, 7) ->
(7, 1) -> (2, 1) -> (2, 4) ->
(4, 4) -> MID
更好的方法:
Java
// Java program to find a path from corner cell to
// middle cell in maze containing positive numbers
import java.io.*;
class GFG {
public static void main (String[] args) {
// Creating the maze
int[][] maze = {
{ 3, 5, 4, 4, 7, 3, 4, 6, 3 },
{ 6, 7, 5, 6, 6, 2, 6, 6, 2 },
{ 3, 3, 4, 3, 2, 5, 4, 7, 2 },
{ 6, 5, 5, 1, 2, 3, 6, 5, 6 },
{ 3, 3, 4, 3, 0, 1, 4, 3, 4 },
{ 3, 5, 4, 3, 2, 2, 3, 3, 5 },
{ 3, 5, 4, 3, 2, 6, 4, 4, 3 },
{ 3, 5, 1, 3, 7, 5, 3, 6, 4 },
{ 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
// Calling the printPath function
printPath(maze,0,0,"");
}
public static void printPath(int[][] maze, int i, int j, String ans){
// If we reach the center cell
if (i == maze.length/2 && j==maze.length/2){
// Make the final answer, Print the
// final answer and Return
ans += "("+i+", "+j+") -> MID";
System.out.println(ans);
return;
}
// If the element at the current position
// in maze is 0, simply Return as it has
// been visited before.
if (maze[i][j]==0){
return;
}
// If element is non-zero, then note
// the element in variable 'k'
int k = maze[i][j];
// Mark the cell visited by making the
// element 0. Don't worry, the element
// is safe in 'k'
maze[i][j]=0;
// Make recursive calls in all 4
// directions pro-actively i.e. if the next
// cell lies in maze or not. Right call
if (j+k ");
}
// down call
if (i+k ");
}
// left call
if (j-k>0){
printPath(maze, i, j-k, ans+"("+i+", "+j+") -> ");
}
// up call
if (i-k>0){
printPath(maze, i-k, j, ans+"("+i+", "+j+") -> ");
}
// Unmark the visited cell by substituting
// its original value from 'k'
maze[i][j] = k;
}
}
Python3
# Python program to find a path from corner cell to
# middle cell in maze containing positive numbers
def printPath(maze, i, j, ans):
# If we reach the center cell
if (i == len(maze) // 2 and j == len(maze) // 2):
# Make the final answer, Prthe
# final answer and Return
ans += "(" + str(i) + ", " + str(j) + ") -> MID";
print(ans);
return;
# If the element at the current position
# in maze is 0, simply Return as it has
# been visited before.
if (maze[i][j] == 0):
return;
# If element is non-zero, then note
# the element in variable 'k'
k = maze[i][j];
# Mark the cell visited by making the
# element 0. Don't worry, the element
# is safe in 'k'
maze[i][j] = 0;
# Make recursive calls in all 4
# directions pro-actively i.e. if the next
# cell lies in maze or not. Right call
if (j + k < len(maze)):
printPath(maze, i, j + k, ans + "(" + str(i) + ", " + str(j) + ") -> ");
# down call
if (i + k < len(maze)):
printPath(maze, i + k, j, ans + "(" + str(i) + ", " + str(j) + ") -> ");
# left call
if (j - k > 0):
printPath(maze, i, j - k, ans + "(" + str(i) + ", " + str(j) + ") -> ");
# up call
if (i - k > 0):
printPath(maze, i - k, j, ans + "(" + str(i) + ", " + str(j) + ") -> ");
# Unmark the visited cell by substituting
# its original value from 'k'
maze[i][j] = k;
# Driver code
if __name__ == '__main__':
# Creating the maze
maze = [[ 3, 5, 4, 4, 7, 3, 4, 6, 3 ],[ 6, 7, 5, 6, 6, 2, 6, 6, 2 ],[ 3, 3, 4, 3, 2, 5, 4, 7, 2 ],
[ 6, 5, 5, 1, 2, 3, 6, 5, 6 ],[ 3, 3, 4, 3, 0, 1, 4, 3, 4 ],[ 3, 5, 4, 3, 2, 2, 3, 3, 5 ],
[ 3, 5, 4, 3, 2, 6, 4, 4, 3 ],[ 3, 5, 1, 3, 7, 5, 3, 6, 4 ],[ 6, 2, 4, 3, 4, 5, 4, 5, 1 ]] ;
# Calling the printPath function
printPath(maze, 0, 0, "");
# This code contributed by gauravrajput1
C#
// C# program to find a path from corner
// cell to middle cell in maze containing
// positive numbers
using System;
class GFG{
// Driver Code
public static void Main(String[] args)
{
// Creating the maze
int[,] maze = {
{ 3, 5, 4, 4, 7, 3, 4, 6, 3 },
{ 6, 7, 5, 6, 6, 2, 6, 6, 2 },
{ 3, 3, 4, 3, 2, 5, 4, 7, 2 },
{ 6, 5, 5, 1, 2, 3, 6, 5, 6 },
{ 3, 3, 4, 3, 0, 1, 4, 3, 4 },
{ 3, 5, 4, 3, 2, 2, 3, 3, 5 },
{ 3, 5, 4, 3, 2, 6, 4, 4, 3 },
{ 3, 5, 1, 3, 7, 5, 3, 6, 4 },
{ 6, 2, 4, 3, 4, 5, 4, 5, 1 }
};
// Calling the printPath function
printPath(maze, 0, 0, "");
}
public static void printPath(int[,] maze, int i,
int j, String ans)
{
// If we reach the center cell
if (i == maze.GetLength(0) / 2 &&
j == maze.GetLength(1) / 2)
{
// Make the readonly answer, Print the
// readonly answer and Return
ans += "(" + i + ", " + j + ") -> MID";
Console.WriteLine(ans);
return;
}
// If the element at the current position
// in maze is 0, simply Return as it has
// been visited before.
if (maze[i, j] == 0)
{
return;
}
// If element is non-zero, then note
// the element in variable 'k'
int k = maze[i, j];
// Mark the cell visited by making the
// element 0. Don't worry, the element
// is safe in 'k'
maze[i, j] = 0;
// Make recursive calls in all 4
// directions pro-actively i.e. if the next
// cell lies in maze or not. Right call
if (j + k < maze.GetLength(1))
{
printPath(maze, i, j + k,
ans + "(" + i +
", " + j + ") -> ");
}
// Down call
if (i + k < maze.GetLength(0))
{
printPath(maze, i + k, j,
ans + "(" + i +
", " + j + ") -> ");
}
// Left call
if (j - k > 0)
{
printPath(maze, i, j - k,
ans + "(" + i +
", " + j + ") -> ");
}
// Up call
if (i - k > 0)
{
printPath(maze, i - k, j,
ans + "(" + i +
", " + j + ") -> ");
}
// Unmark the visited cell by substituting
// its original value from 'k'
maze[i, j] = k;
}
}
// This code is contributed by gauravrajput1
输出:
(0, 0) -> (0, 3) -> (0, 7) ->
(6, 7) -> (6, 3) -> (3, 3) ->
(3, 4) -> (5, 4) -> (5, 2) ->
(1, 2) -> (1, 7) -> (7, 7) ->
(7, 1) -> (2, 1) -> (2, 4) ->
(4, 4) -> MID