📜  带有N门和1把钥匙的迷宫

📅  最后修改于: 2021-04-24 19:54:24             🧑  作者: Mango

给定一个N * N二进制迷宫,其中0表示可以访问该位置,而1表示没有钥匙就不能访问该位置,任务是查找是否有可能从顶部访问右下角的单元格-一路只有一个键的左单元格。如果可能,请打印“是”,否则打印“否”

例子:

方法:可以使用递归来解决此问题,对于非常可能的移动,如果当前单元格为0,则在不更改键状态的情况下,检查是否为目标,否则继续向前移动。如果当前单元格为1,则必须使用该键,现在,对于进一步的移动,该键将被设置为false,即它将永远不会在同一路径上再次使用。如果有任何路径到达目的地,则打印“是”,否则打印“否”

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Recursive function to check whether there is 
// a path from the top left cell to the 
// bottom right cell of the maze
bool findPath(vector> maze,
              int xpos, int ypos, bool key)
{
     
    // Check whether the current cell is
    // within the maze
    if (xpos < 0 || xpos >= maze.size() ||
        ypos < 0 || ypos >= maze.size())
        return false;
 
    // If key is required to move further
    if (maze[xpos][ypos] == '1')
    {
         
        // If the key hasn't been used before
        if (key == true)
 
            // If current cell is the destination
            if (xpos == maze.size() - 1 &&
                ypos == maze.size() - 1)
                return true;
 
        // Either go down or right
        return findPath(maze, xpos + 1,
                        ypos, false) ||
               findPath(maze, xpos,
                        ypos + 1, false);
 
        // Key has been used before
        return false;
    }
     
    // If current cell is the destination
    if (xpos == maze.size() - 1 &&
        ypos == maze.size() - 1)
        return true;
 
    // Either go down or right
    return findPath(maze, xpos + 1,
                    ypos, key) ||
           findPath(maze, xpos,
                    ypos + 1, key);
}
 
bool mazeProb(vector> maze,
              int xpos, int ypos)
{
    bool key = true;
    if (findPath(maze, xpos, ypos, key))
        return true;
         
    return false;
}
 
// Driver code
int main()
{
    vector> maze = { { '0', '0', '1' },
                                 { '1', '0', '1' },
                                 { '1', '1', '0' } };
    int n = maze.size();
 
    // If there is a path from the cell (0, 0)
    if (mazeProb(maze, 0, 0))
        cout << "Yes";
    else
        cout << "No";
}
 
// This code is contributed by grand_master


Java
// Java implementation of the approach
import java.io.*;
import java.util.ArrayList;
 
class GFG{
 
// Recursive function to check whether there
// is a path from the top left cell to the
// bottom right cell of the maze
static boolean findPath(
    ArrayList> maze,
    int xpos, int ypos, boolean key)
{
     
    // Check whether the current cell is
    // within the maze
    if (xpos < 0 || xpos >= maze.size() ||
        ypos < 0 || ypos >= maze.size())
        return false;
 
    // If key is required to move further
    if (maze.get(xpos).get(ypos) == '1')
    {
         
        // If the key hasn't been used before
        if (key == true)
         
            // If current cell is the destination
            if (xpos == maze.size() - 1 &&
                ypos == maze.size() - 1)
                return true;
 
        // Either go down or right
        return findPath(maze, xpos + 1, ypos, false) ||
               findPath(maze, xpos, ypos + 1, false);
    }
 
    // If current cell is the destination
    if (xpos == maze.size() - 1 &&
        ypos == maze.size() - 1)
        return true;
 
    // Either go down or right
    return findPath(maze, xpos + 1, ypos, key) ||
           findPath(maze, xpos, ypos + 1, key);
}
 
static boolean mazeProb(
    ArrayList> maze,
    int xpos, int ypos)
{
    boolean key = true;
     
    if (findPath(maze, xpos, ypos, key))
        return true;
 
    return false;
}
 
// Driver code
public static void main(String[] args)
{
    int size = 3;
    ArrayList> maze =
    new ArrayList>(size);
     
    for(int i = 0; i < size; i++)
    {
        maze.add(new ArrayList());
    }
 
    // We are making these
    //{ { '0', '0', '1' },
    //  { '1', '0', '1' },
    //  { '1', '1', '0' } };
    maze.get(0).add(0);
    maze.get(0).add(0);
    maze.get(0).add(1);
    maze.get(1).add(1);
    maze.get(1).add(0);
    maze.get(1).add(1);
    maze.get(2).add(1);
    maze.get(2).add(1);
    maze.get(2).add(0);
     
    // If there is a path from the cell (0, 0)
    if (mazeProb(maze, 0, 0))
        System.out.print("Yes");
    else
        System.out.print("No");
}
}
 
// This code is contributed by sujitmeshram


Python3
# Python3 implementation of the approach
 
# Recursive function to check whether there is
# a path from the top left cell to the
# bottom right cell of the maze
def findPath(maze, xpos, ypos, key):
 
    # Check whether the current cell is
    # within the maze
    if xpos < 0 or xpos >= len(maze) or ypos < 0 \
                            or ypos >= len(maze):
        return False
 
    # If key is required to move further
    if maze[xpos][ypos] == '1':
 
        # If the key hasn't been used before
        if key == True:
 
            # If current cell is the destination
            if xpos == len(maze)-1 and ypos == len(maze)-1:
                return True
 
            # Either go down or right
            return findPath(maze, xpos + 1, ypos, False) or \
            findPath(maze, xpos, ypos + 1, False)
 
        # Key has been used before
        return False
 
    # If current cell is the destination
    if xpos == len(maze)-1 and ypos == len(maze)-1:
        return True
 
    # Either go down or right
    return findPath(maze, xpos + 1, ypos, key) or \
           findPath(maze, xpos, ypos + 1, key)
 
 
def mazeProb(maze, xpos, ypos):
    key = True
    if findPath(maze, xpos, ypos, key):
        return True
    return False
 
# Driver code
if __name__ == "__main__":
 
    maze = [['0', '0', '1'],
            ['1', '0', '1'],
            ['1', '1', '0']]
    n = len(maze)
     
    # If there is a path from the cell (0, 0)
    if mazeProb(maze, 0, 0):
        print("Yes")
    else:
        print("No")


C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
 
class GFG{
 
// Recursive function to check whether there
// is a path from the top left cell to the
// bottom right cell of the maze
static bool findPath(List> maze,
                     int xpos, int ypos, bool key)
{
     
    // Check whether the current cell is
    // within the maze
    if (xpos < 0 || xpos >= maze.Count ||
        ypos < 0 || ypos >= maze.Count)
        return false;
 
    // If key is required to move further
    if (maze[xpos][ypos] == '1')
    {
         
        // If the key hasn't been used before
        if (key == true)
         
            // If current cell is the destination
            if (xpos == maze.Count - 1 &&
                ypos == maze.Count - 1)
                return true;
 
        // Either go down or right
        return findPath(maze, xpos + 1, ypos, false) ||
               findPath(maze, xpos, ypos + 1, false);
    }
 
    // If current cell is the destination
    if (xpos == maze.Count - 1 &&
        ypos == maze.Count - 1)
        return true;
 
    // Either go down or right
    return findPath(maze, xpos + 1, ypos, key) ||
           findPath(maze, xpos, ypos + 1, key);
}
 
static bool mazeProb(List> maze,
                     int xpos, int ypos)
{
    bool key = true;
     
    if (findPath(maze, xpos, ypos, key))
        return true;
 
    return false;
}
 
// Driver code
public static void Main(String[] args)
{
    int size = 3;
    List> maze =
    new List>(size);
     
    for(int i = 0; i < size; i++)
    {
        maze.Add(new List());
    }
 
    // We are making these
    //{ { '0', '0', '1' },
    //  { '1', '0', '1' },
    //  { '1', '1', '0' } };
    maze[0].Add(0);
    maze[0].Add(0);
    maze[0].Add(1);
    maze[1].Add(1);
    maze[1].Add(0);
    maze[1].Add(1);
    maze[2].Add(1);
    maze[2].Add(1);
    maze[2].Add(0);
     
    // If there is a path from the cell (0, 0)
    if (mazeProb(maze, 0, 0))
        Console.Write("Yes");
    else
        Console.Write("No");
}
}
 
// This code is contributed by gauravrajput1


输出:
Yes

时间复杂度: O(2 N )