Encuentre la ruta segura más corta en un camino con minas terrestres

Dada una ruta en forma de array rectangular con pocas minas terrestres colocadas arbitrariamente (marcada como 0), calcule la longitud de la ruta segura más corta posible desde cualquier celda de la primera columna hasta cualquier celda de la última columna de la array. Tenemos que evitar las minas terrestres y sus cuatro celdas adyacentes (izquierda, derecha, arriba y abajo) ya que tampoco son seguras. Solo se nos permite movernos a celdas adyacentes que no son minas terrestres. es decir, la ruta no puede contener movimientos diagonales.

Ejemplos:  

Input: 
A 12 x 10 matrix with landmines marked as 0

[ 1  1  1  1  1  1  1  1  1  1 ]
[ 1  0  1  1  1  1  1  1  1  1 ]
[ 1  1  1  0  1  1  1  1  1  1 ]
[ 1  1  1  1  0  1  1  1  1  1 ]
[ 1  1  1  1  1  1  1  1  1  1 ]
[ 1  1  1  1  1  0  1  1  1  1 ]
[ 1  0  1  1  1  1  1  1  0  1 ]
[ 1  1  1  1  1  1  1  1  1  1 ]
[ 1  1  1  1  1  1  1  1  1  1 ]
[ 0  1  1  1  1  0  1  1  1  1 ]
[ 1  1  1  1  1  1  1  1  1  1 ]
[ 1  1  1  0  1  1  1  1  1  1 ]

Output:  
Length of shortest safe route is 13 (Highlighted in Bold)

La idea es usar Backtracking. Primero marcamos todas las celdas adyacentes de las minas terrestres como inseguras. Luego, para cada celda segura de la primera columna de la array, avanzamos en todas las direcciones permitidas y verificamos recursivamente si conducen al destino o no. Si se encuentra el destino, actualizamos el valor de la ruta más corta; de lo contrario, si ninguna de las soluciones anteriores funciona, devolvemos falso desde nuestra función.

A continuación se muestra la implementación de la idea anterior:

C++

// C++ program to find shortest safe Route in
// the matrix with landmines
#include <bits/stdc++.h>
using namespace std;
#define R 12
#define C 10
 
// These arrays are used to get row and column
// numbers of 4 neighbours of a given cell
int rowNum[] = { -1, 0, 0, 1 };
int colNum[] = { 0, -1, 1, 0 };
 
// A function to check if a given cell (x, y)
// can be visited or not
bool isSafe(int mat[R][C], int visited[R][C],
            int x, int y)
{
    if (mat[x][y] == 0 || visited[x][y])
        return false;
 
    return true;
}
 
// A function to check if a given cell (x, y) is
// a valid cell or not
bool isValid(int x, int y)
{
    if (x < R && y < C && x >= 0 && y >= 0)
        return true;
 
    return false;
}
 
// A function to mark all adjacent cells of
// landmines as unsafe. Landmines are shown with
// number 0
void markUnsafeCells(int mat[R][C])
{
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            // if a landmines is found
            if (mat[i][j] == 0)
            {
              // mark all adjacent cells
              for (int k = 0; k < 4; k++)
                if (isValid(i + rowNum[k], j + colNum[k]))
                    mat[i + rowNum[k]][j + colNum[k]] = -1;
            }
        }
    }
 
    // mark all found adjacent cells as unsafe
    for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            if (mat[i][j] == -1)
                mat[i][j] = 0;
        }
    }
 
    // Uncomment below lines to print the path
    /*for (int i = 0; i < R; i++)
    {
        for (int j = 0; j < C; j++)
        {
            cout << std::setw(3) << mat[i][j];
        }
        cout << endl;
    }*/
}
 
// Function to find shortest safe Route in the
// matrix with landmines
// mat[][] - binary input matrix with safe cells marked as 1
// visited[][] - store info about cells already visited in
// current route
// (i, j) are coordinates of the current cell
// min_dist --> stores minimum cost of shortest path so far
// dist --> stores current path cost
void findShortestPathUtil(int mat[R][C], int visited[R][C],
                          int i, int j, int &min_dist, int dist)
{
    // if destination is reached
    if (j == C-1)
    {
        // update shortest path found so far
        min_dist = min(dist, min_dist);
        return;
    }
 
    // if current path cost exceeds minimum so far
    if (dist > min_dist)
        return;
 
    // include (i, j) in current path
    visited[i][j] = 1;
 
    // Recurse for all safe adjacent neighbours
    for (int k = 0; k < 4; k++)
    {
        if (isValid(i + rowNum[k], j + colNum[k]) &&
            isSafe(mat, visited, i + rowNum[k], j + colNum[k]))
        {
            findShortestPathUtil(mat, visited, i + rowNum[k],
                           j + colNum[k], min_dist, dist + 1);
        }
    }
 
    // Backtrack
    visited[i][j] = 0;
}
 
// A wrapper function over findshortestPathUtil()
void findShortestPath(int mat[R][C])
{
    // stores minimum cost of shortest path so far
    int min_dist = INT_MAX;
 
    // create a boolean matrix to store info about
    // cells already visited in current route
    int visited[R][C];
 
    // mark adjacent cells of landmines as unsafe
    markUnsafeCells(mat);
 
    // start from first column and take minimum
    for (int i = 0; i < R; i++)
    {
        // if path is safe from current cell
        if (mat[i][0] == 1)
        {
            // initialize visited to false
            memset(visited, 0, sizeof visited);
 
            // find shortest route from (i, 0) to any
            // cell of last column (x, C - 1) where
            // 0 <= x < R
            findShortestPathUtil(mat, visited, i, 0,
                                 min_dist, 0);
 
            // if min distance is already found
            if(min_dist == C - 1)
                break;
        }
    }
 
    // if destination can be reached
    if (min_dist != INT_MAX)
        cout << "Length of shortest safe route is "
             << min_dist;
 
    else // if the destination is not reachable
        cout << "Destination not reachable from "
             << "given source";
}
 
// Driver code
int main()
{
    // input matrix with landmines shown with number 0
    int mat[R][C] =
    {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }
    };
 
    // find shortest path
    findShortestPath(mat);
 
    return 0;
}

Java

// Java program to find shortest safe Route
// in the matrix with landmines
import java.util.Arrays;
 
class GFG{
 
static final int R = 12;
static final int C = 10;
 
// These arrays are used to get row and column
// numbers of 4 neighbours of a given cell
static int rowNum[] = { -1, 0, 0, 1 };
static int colNum[] = { 0, -1, 1, 0 };
 
static int min_dist;
 
// A function to check if a given cell (x, y)
// can be visited or not
static boolean isSafe(int[][] mat, boolean[][] visited,
                      int x, int y)
{
    if (mat[x][y] == 0 || visited[x][y])
        return false;
 
    return true;
}
 
// A function to check if a given cell (x, y) is
// a valid cell or not
static boolean isValid(int x, int y)
{
    if (x < R && y < C && x >= 0 && y >= 0)
        return true;
 
    return false;
}
 
// A function to mark all adjacent cells of
// landmines as unsafe. Landmines are shown with
// number 0
static void markUnsafeCells(int[][] mat)
{
    for(int i = 0; i < R; i++)
    {
        for(int j = 0; j < C; j++)
        {
             
            // If a landmines is found
            if (mat[i][j] == 0)
            {
                 
                // Mark all adjacent cells
                for(int k = 0; k < 4; k++)
                    if (isValid(i + rowNum[k], j + colNum[k]))
                        mat[i + rowNum[k]][j + colNum[k]] = -1;
            }
        }
    }
 
    // Mark all found adjacent cells as unsafe
    for(int i = 0; i < R; i++)
    {
        for(int j = 0; j < C; j++)
        {
            if (mat[i][j] == -1)
                mat[i][j] = 0;
        }
    }
 
    // Uncomment below lines to print the path
    /*
     * for (int i = 0; i < R; i++) {
     * for (int j = 0; j < C; j++) { cout <<
     * std::setw(3) << mat[i][j]; } cout << endl; }
     */
}
 
// Function to find shortest safe Route in the
// matrix with landmines
// mat[][] - binary input matrix with safe cells marked as 1
// visited[][] - store info about cells already visited in
// current route
// (i, j) are coordinates of the current cell
// min_dist --> stores minimum cost of shortest path so far
// dist --> stores current path cost
static void findShortestPathUtil(int[][] mat,
                                 boolean[][] visited,
                                 int i, int j, int dist)
{
     
    // If destination is reached
    if (j == C - 1)
    {
         
        // Update shortest path found so far
        min_dist = Math.min(dist, min_dist);
        return;
    }
     
    // If current path cost exceeds minimum so far
    if (dist > min_dist)
        return;
 
    // include (i, j) in current path
    visited[i][j] = true;
 
    // Recurse for all safe adjacent neighbours
    for(int k = 0; k < 4; k++)
    {
        if (isValid(i + rowNum[k], j + colNum[k]) &&
            isSafe(mat, visited, i + rowNum[k],
                                 j + colNum[k]))
        {
            findShortestPathUtil(mat, visited, i + rowNum[k],
                             j + colNum[k], dist + 1);
        }
    }
 
    // Backtrack
    visited[i][j] = false;
}
 
// A wrapper function over findshortestPathUtil()
static void findShortestPath(int[][] mat)
{
     
    // Stores minimum cost of shortest path so far
    min_dist = Integer.MAX_VALUE;
     
    // Create a boolean matrix to store info about
    // cells already visited in current route
    boolean[][] visited = new boolean[R][C];
 
    // Mark adjacent cells of landmines as unsafe
    markUnsafeCells(mat);
 
    // Start from first column and take minimum
    for(int i = 0; i < R; i++)
    {
         
        // If path is safe from current cell
        if (mat[i][0] == 1)
        {
             
            // Initialize visited to false
            for(int k = 0; k < R; k++)
            {
                Arrays.fill(visited[k], false);
            }
 
            // Find shortest route from (i, 0) to any
            // cell of last column (x, C - 1) where
            // 0 <= x < R
            findShortestPathUtil(mat, visited, i, 0, 0);
 
            // If min distance is already found
            if (min_dist == C - 1)
                break;
        }
    }
     
    // If destination can be reached
    if (min_dist != Integer.MAX_VALUE)
        System.out.println("Length of shortest " +
                           "safe route is " + min_dist);
 
    else
     
        // If the destination is not reachable
        System.out.println("Destination not " +
                           "reachable from given source");
}
 
// Driver code
public static void main(String[] args)
{
     
    // Input matrix with landmines shown with number 0
    int[][] mat = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 } };
 
    // Find shortest path
    findShortestPath(mat);
}
}
 
// This code is contributed by sanjeev2552

Python3

# Python3 program to find shortest safe Route
# in the matrix with landmines
import sys
 
R = 12
C = 10
 
# These arrays are used to get row and column
# numbers of 4 neighbours of a given cell
rowNum = [ -1, 0, 0, 1 ]
colNum = [ 0, -1, 1, 0 ]
 
min_dist = sys.maxsize
 
# A function to check if a given cell (x, y)
# can be visited or not
def isSafe(mat, visited, x, y):
 
    if (mat[x][y] == 0 or visited[x][y]):
        return False
 
    return True
 
# A function to check if a given cell (x, y) is
# a valid cell or not
def isValid(x, y):
 
    if (x < R and y < C and x >= 0 and y >= 0):
        return True
 
    return False
 
# A function to mark all adjacent cells of
# landmines as unsafe. Landmines are shown with
# number 0
def markUnsafeCells(mat):
 
    for i in range(R):
        for j in range(C):
            # If a landmines is found
            if (mat[i][j] == 0):
                # Mark all adjacent cells
                for k in range(4):
                    if (isValid(i + rowNum[k], j + colNum[k])):
                        mat[i + rowNum[k]][j + colNum[k]] = -1
 
    # Mark all found adjacent cells as unsafe
    for i in range(R):
        for j in range(C):
            if (mat[i][j] == -1):
                mat[i][j] = 0
 
    """ Uncomment below lines to print the path
    /*
     * for (int i = 0; i < R; i++) {
     * for (int j = 0; j < C; j++) { cout <<
     * std::setw(3) << mat[i][j]; } cout << endl; }
     *"""
 
# Function to find shortest safe Route in the
# matrix with landmines
# mat[][] - binary input matrix with safe cells marked as 1
# visited[][] - store info about cells already visited in
# current route
# (i, j) are coordinates of the current cell
# min_dist --> stores minimum cost of shortest path so far
# dist --> stores current path cost
def findShortestPathUtil(mat, visited, i, j, dist):
     
    global min_dist
 
    # If destination is reached
    if (j == C - 1):
        # Update shortest path found so far
        min_dist = min(dist, min_dist)
        return
 
    # If current path cost exceeds minimum so far
    if (dist > min_dist):
        return
 
    # include (i, j) in current path
    visited[i][j] = True
 
    # Recurse for all safe adjacent neighbours
    for k in range(4):
        if (isValid(i + rowNum[k], j + colNum[k]) and isSafe(mat, visited, i + rowNum[k], j + colNum[k])):
            findShortestPathUtil(mat, visited, i + rowNum[k], j + colNum[k], dist + 1)
 
    # Backtrack
    visited[i][j] = False
 
# A wrapper function over findshortestPathUtil()
def findShortestPath(mat):
     
    global min_dist
 
    # Stores minimum cost of shortest path so far
    min_dist = sys.maxsize
 
    # Create a boolean matrix to store info about
    # cells already visited in current route
    visited = [[False for i in range(C)] for j in range(R)]
 
    # Mark adjacent cells of landmines as unsafe
    markUnsafeCells(mat)
 
    # Start from first column and take minimum
    for i in range(R):
        # If path is safe from current cell
        if (mat[i][0] == 1):
            # Find shortest route from (i, 0) to any
            # cell of last column (x, C - 1) where
            # 0 <= x < R
            findShortestPathUtil(mat, visited, i, 0, 0)
 
            # If min distance is already found
            if (min_dist == C - 1):
                break
 
    # If destination can be reached
    if (min_dist != sys.maxsize):
        print("Length of shortest safe route is", min_dist)
    else:
        # If the destination is not reachable
        print("Destination not reachable from given source")
         
mat = [
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 ],
        [ 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ] ]
   
# Find shortest path
findShortestPath(mat)
 
# This code is contributed by mukesh07.

C#

// C# program to find shortest safe Route
// in the matrix with landmines
using System;
using System.Collections.Generic;
class GFG {
     
    static int R = 12;
    static int C = 10;
      
    // These arrays are used to get row and column
    // numbers of 4 neighbours of a given cell
    static int[] rowNum = { -1, 0, 0, 1 };
    static int[] colNum = { 0, -1, 1, 0 };
      
    static int min_dist;
      
    // A function to check if a given cell (x, y)
    // can be visited or not
    static bool isSafe(int[,] mat, bool[,] visited, int x, int y)
    {
        if (mat[x,y] == 0 || visited[x,y])
            return false;
      
        return true;
    }
      
    // A function to check if a given cell (x, y) is
    // a valid cell or not
    static bool isValid(int x, int y)
    {
        if (x < R && y < C && x >= 0 && y >= 0)
            return true;
      
        return false;
    }
      
    // A function to mark all adjacent cells of
    // landmines as unsafe. Landmines are shown with
    // number 0
    static void markUnsafeCells(int[,] mat)
    {
        for(int i = 0; i < R; i++)
        {
            for(int j = 0; j < C; j++)
            {
                  
                // If a landmines is found
                if (mat[i,j] == 0)
                {
                      
                    // Mark all adjacent cells
                    for(int k = 0; k < 4; k++)
                        if (isValid(i + rowNum[k], j + colNum[k]))
                            mat[i + rowNum[k],j + colNum[k]] = -1;
                }
            }
        }
      
        // Mark all found adjacent cells as unsafe
        for(int i = 0; i < R; i++)
        {
            for(int j = 0; j < C; j++)
            {
                if (mat[i,j] == -1)
                    mat[i,j] = 0;
            }
        }
      
        // Uncomment below lines to print the path
        /*
         * for (int i = 0; i < R; i++) {
         * for (int j = 0; j < C; j++) { cout <<
         * std::setw(3) << mat[i][j]; } cout << endl; }
         */
    }
      
    // Function to find shortest safe Route in the
    // matrix with landmines
    // mat[][] - binary input matrix with safe cells marked as 1
    // visited[][] - store info about cells already visited in
    // current route
    // (i, j) are coordinates of the current cell
    // min_dist --> stores minimum cost of shortest path so far
    // dist --> stores current path cost
    static void findShortestPathUtil(int[,] mat,
                                     bool[,] visited,
                                     int i, int j, int dist)
    {
          
        // If destination is reached
        if (j == C - 1)
        {
              
            // Update shortest path found so far
            min_dist = Math.Min(dist, min_dist);
            return;
        }
          
        // If current path cost exceeds minimum so far
        if (dist > min_dist)
            return;
      
        // include (i, j) in current path
        visited[i,j] = true;
      
        // Recurse for all safe adjacent neighbours
        for(int k = 0; k < 4; k++)
        {
            if (isValid(i + rowNum[k], j + colNum[k]) &&
                isSafe(mat, visited, i + rowNum[k], j + colNum[k]))
            {
                findShortestPathUtil(mat, visited, i + rowNum[k], j + colNum[k], dist + 1);
            }
        }
      
        // Backtrack
        visited[i,j] = false;
    }
      
    // A wrapper function over findshortestPathUtil()
    static void findShortestPath(int[,] mat)
    {
          
        // Stores minimum cost of shortest path so far
        min_dist = Int32.MaxValue;
          
        // Create a boolean matrix to store info about
        // cells already visited in current route
        bool[,] visited = new bool[R,C];
      
        // Mark adjacent cells of landmines as unsafe
        markUnsafeCells(mat);
      
        // Start from first column and take minimum
        for(int i = 0; i < R; i++)
        {
              
            // If path is safe from current cell
            if (mat[i,0] == 1)
            {
                // Find shortest route from (i, 0) to any
                // cell of last column (x, C - 1) where
                // 0 <= x < R
                findShortestPathUtil(mat, visited, i, 0, 0);
      
                // If min distance is already found
                if (min_dist == C - 1)
                    break;
            }
        }
          
        // If destination can be reached
        if (min_dist != Int32.MaxValue)
            Console.WriteLine("Length of shortest " +
                               "safe route is " + min_dist);
      
        else
          
            // If the destination is not reachable
            Console.WriteLine("Destination not " +
                               "reachable from given source");
    }
     
  static void Main()
  {
     
    // Input matrix with landmines shown with number 0
    int[,] mat = {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 } };
  
    // Find shortest path
    findShortestPath(mat);
  }
}
 
// This code is contributed by rameshtravel07.

Javascript

<script>
    // Javascript program to find shortest safe Route
    // in the matrix with landmines
     
    let R = 12;
    let C = 10;
 
    // These arrays are used to get row and column
    // numbers of 4 neighbours of a given cell
    let rowNum = [ -1, 0, 0, 1 ];
    let colNum = [ 0, -1, 1, 0 ];
 
    let min_dist;
 
    // A function to check if a given cell (x, y)
    // can be visited or not
    function isSafe(mat, visited, x, y)
    {
        if (mat[x][y] == 0 || visited[x][y])
            return false;
 
        return true;
    }
 
    // A function to check if a given cell (x, y) is
    // a valid cell or not
    function isValid(x, y)
    {
        if (x < R && y < C && x >= 0 && y >= 0)
            return true;
 
        return false;
    }
 
    // A function to mark all adjacent cells of
    // landmines as unsafe. Landmines are shown with
    // number 0
    function markUnsafeCells(mat)
    {
        for(let i = 0; i < R; i++)
        {
            for(let j = 0; j < C; j++)
            {
 
                // If a landmines is found
                if (mat[i][j] == 0)
                {
 
                    // Mark all adjacent cells
                    for(let k = 0; k < 4; k++)
                        if (isValid(i + rowNum[k], j + colNum[k]))
                            mat[i + rowNum[k]][j + colNum[k]] = -1;
                }
            }
        }
 
        // Mark all found adjacent cells as unsafe
        for(let i = 0; i < R; i++)
        {
            for(let j = 0; j < C; j++)
            {
                if (mat[i][j] == -1)
                    mat[i][j] = 0;
            }
        }
 
        // Uncomment below lines to print the path
        /*
         * for (int i = 0; i < R; i++) {
         * for (int j = 0; j < C; j++) { cout <<
         * std::setw(3) << mat[i][j]; } cout << endl; }
         */
    }
 
    // Function to find shortest safe Route in the
    // matrix with landmines
    // mat[][] - binary input matrix with safe cells marked as 1
    // visited[][] - store info about cells already visited in
    // current route
    // (i, j) are coordinates of the current cell
    // min_dist --> stores minimum cost of shortest path so far
    // dist --> stores current path cost
    function findShortestPathUtil(mat, visited, i, j, dist)
    {
 
        // If destination is reached
        if (j == C - 1)
        {
 
            // Update shortest path found so far
            min_dist = Math.min(dist, min_dist);
            return;
        }
 
        // If current path cost exceeds minimum so far
        if (dist > min_dist)
            return;
 
        // include (i, j) in current path
        visited[i][j] = true;
 
        // Recurse for all safe adjacent neighbours
        for(let k = 0; k < 4; k++)
        {
            if (isValid(i + rowNum[k], j + colNum[k]) &&
                isSafe(mat, visited, i + rowNum[k],
                                     j + colNum[k]))
            {
                findShortestPathUtil(mat, visited, i + rowNum[k],
                                 j + colNum[k], dist + 1);
            }
        }
 
        // Backtrack
        visited[i][j] = false;
    }
 
    // A wrapper function over findshortestPathUtil()
    function findShortestPath(mat)
    {
 
        // Stores minimum cost of shortest path so far
        min_dist = Number.MAX_VALUE;
 
        // Create a boolean matrix to store info about
        // cells already visited in current route
        let visited = new Array(R);
         
        for(let i = 0; i < R; i++)
        {
            visited[i] = new Array(C);
            for(let j = 0; j < C; j++)
            {
                visited[i][j] = false;
            }
        }
 
        // Mark adjacent cells of landmines as unsafe
        markUnsafeCells(mat);
 
        // Start from first column and take minimum
        for(let i = 0; i < R; i++)
        {
            // If path is safe from current cell
            if (mat[i][0] == 1)
            {
 
                // Find shortest route from (i, 0) to any
                // cell of last column (x, C - 1) where
                // 0 <= x < R
                findShortestPathUtil(mat, visited, i, 0, 0);
 
                // If min distance is already found
                if (min_dist == C - 1)
                    break;
            }
        }
 
        // If destination can be reached
        if (min_dist != Number.MAX_VALUE)
            document.write("Length of shortest " +
                               "safe route is " + min_dist + "</br>");
 
        else
 
            // If the destination is not reachable
            document.write("Destination not " +
                               "reachable from given source" + "</br>");
    }
     
    // Input matrix with landmines shown with number 0
    let mat = [
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 ],
        [ 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ] ];
  
    // Find shortest path
    findShortestPath(mat);
 
// This code is contributed by decode2207.
</script>
Producción

Length of shortest safe route is 13

Otro método: se puede resolver en tiempo polinomial con la ayuda de Breadth First Search. Ponga en cola las celdas con 1 valor en la cola con la distancia como 0. A medida que avanza el BFS, se calcula la ruta más corta a cada celda desde la primera columna. Finalmente, para las celdas alcanzables en la última columna, genere la distancia mínima.

La implementación en C++ es la siguiente: 

C++

// C++ program to find shortest safe Route in
// the matrix with landmines
#include <bits/stdc++.h>
using namespace std;
 
#define R 12
#define C 10
 
struct Key{
    int x,y;
    Key(int i,int j){ x=i;y=j;};
};
 
// These arrays are used to get row and column
// numbers of 4 neighbours of a given cell
int rowNum[] = { -1, 0, 0, 1 };
int colNum[] = { 0, -1, 1, 0 };
 
// A function to check if a given cell (x, y) is
// a valid cell or not
bool isValid(int x, int y)
{
    if (x < R && y < C && x >= 0 && y >= 0)
        return true;
 
    return false;
}
 
// A function to mark all adjacent cells of
// landmines as unsafe. Landmines are shown with
// number 0
void findShortestPath(int mat[R][C]){
    int i,j;
 
    for (i = 0; i < R; i++)
    {
        for (j = 0; j < C; j++)
        {
            // if a landmines is found
            if (mat[i][j] == 0)
            {
            // mark all adjacent cells
            for (int k = 0; k < 4; k++)
                if (isValid(i + rowNum[k], j + colNum[k]))
                    mat[i + rowNum[k]][j + colNum[k]] = -1;
            }
        }
    }
// mark all found adjacent cells as unsafe
    for (i = 0; i < R; i++)
    {
        for (j = 0; j < C; j++)
        {
            if (mat[i][j] == -1)
                mat[i][j] = 0;
        }
    }
 
    int dist[R][C];
 
    for(i=0;i<R;i++){
        for(j=0;j<C;j++)
            dist[i][j] = -1;
    }
    queue<Key> q;
 
    for(i=0;i<R;i++){
        if(mat[i][0] == 1){
            q.push(Key(i,0));
            dist[i][0] = 0;
        }
    }
 
    while(!q.empty()){
        Key k = q.front();
        q.pop();
 
        int d = dist[k.x][k.y];
 
        int x = k.x;
        int y = k.y;
 
        for (int k = 0; k < 4; k++) {
            int xp = x + rowNum[k];
            int yp = y + colNum[k];
            if(isValid(xp,yp) && dist[xp][yp] == -1 && mat[xp][yp] == 1){
                dist[xp][yp] = d+1;
                q.push(Key(xp,yp));
            }
        }
    }
    // stores minimum cost of shortest path so far
    int ans = INT_MAX;
    // start from first column and take minimum
    for(i=0;i<R;i++){
        if(mat[i][C-1] == 1 && dist[i][C-1] != -1){
            ans = min(ans,dist[i][C-1]);
        }
    }
     
    // if destination can be reached
    if(ans == INT_MAX)
        cout << "NOT POSSIBLE\n";
         
    else// if the destination is not reachable
        cout << "Length of shortest safe route is " << ans << endl;
}
 
// Driver code
int main(){
     
    // input matrix with landmines shown with number 0
    int mat[R][C] =
    {
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 }
    };
     
    // find shortest path
    findShortestPath(mat);
}

Java

// Java program to find shortest safe Route in
// the matrix with landmines
 
import java.util.LinkedList;
import java.util.Queue;
 
public class GFG {
 
    static class Key {
        int x, y;
        Key(int i, int j)
        {
            x = i;
            y = j;
        };
    }
 
    static int R = 12, C = 10;
    // These arrays are used to get row and column
    // numbers of 4 neighbours of a given cell
    static int rowNum[] = { -1, 0, 0, 1 };
    static int colNum[] = { 0, -1, 1, 0 };
 
    // A function to check if a given cell (x, y) is
    // a valid cell or not
    static boolean isValid(int x, int y)
    {
        if (x < R && y < C && x >= 0 && y >= 0)
            return true;
 
        return false;
    }
 
    // A function to mark all adjacent cells of
    // landmines as unsafe. Landmines are shown with
    // number 0
    static void findShortestPath(int mat[][])
    {
        int i, j;
 
        for (i = 0; i < R; i++) {
            for (j = 0; j < C; j++) {
                // if a landmines is found
                if (mat[i][j] == 0) {
                    // mark all adjacent cells
                    for (int k = 0; k < 4; k++)
                        if (isValid(i + rowNum[k],
                                    j + colNum[k]))
                            mat[i + rowNum[k]]
                               [j + colNum[k]]
                                = -1;
                }
            }
        }
        // mark all found adjacent cells as unsafe
        for (i = 0; i < R; i++) {
            for (j = 0; j < C; j++) {
                if (mat[i][j] == -1)
                    mat[i][j] = 0;
            }
        }
 
        int dist[][] = new int[R][C];
 
        for (i = 0; i < R; i++) {
            for (j = 0; j < C; j++)
                dist[i][j] = -1;
        }
        Queue<Key> q = new LinkedList<Key>();
 
        for (i = 0; i < R; i++) {
            if (mat[i][0] == 1) {
                q.add(new Key(i, 0));
                dist[i][0] = 0;
            }
        }
 
        while (!q.isEmpty()) {
            Key k = q.peek();
            q.poll();
 
            int d = dist[k.x][k.y];
 
            int x = k.x;
            int y = k.y;
 
            for (int ki = 0; ki < 4; ki++) {
                int xp = x + rowNum[ki];
                int yp = y + colNum[ki];
                if (isValid(xp, yp) && dist[xp][yp] == -1
                    && mat[xp][yp] == 1) {
                    dist[xp][yp] = d + 1;
                    q.add(new Key(xp, yp));
                }
            }
        }
        // stores minimum cost of shortest path so far
        int ans = Integer.MAX_VALUE;
        // start from first column and take minimum
        for (i = 0; i < R; i++) {
            if (mat[i][C - 1] == 1
                && dist[i][C - 1] != -1) {
                ans = Math.min(ans, dist[i][C - 1]);
            }
        }
 
        // if destination can be reached
        if (ans == Integer.MAX_VALUE)
            System.out.println("NOT POSSIBLE");
 
        else // if the destination is not reachable
            System.out.println(
                "Length of shortest safe route is " + ans);
    }
 
    // Driver code
    public static void main(String[] args)
    {
 
        // input matrix with landmines shown with number 0
        int mat[][] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                        { 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 },
                        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 },
                        { 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 },
                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                        { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                        { 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 },
                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                        { 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 },
                        { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
                        { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 } };
 
        // find shortest path
        findShortestPath(mat);
    }
}
 
// This code is contributed by Lovely Jain

Python3

# Python program to find shortest safe Route in
# the matrix with landmines
import sys
 
R = 12
C = 10
 
class Key:
    def __init__(self,i, j):
        self.x = i
        self.y = j
 
# These arrays are used to get row and column
# numbers of 4 neighbours of a given cell
rowNum = [ -1, 0, 0, 1 ]
colNum = [ 0, -1, 1, 0 ]
 
# A function to check if a given cell (x, y) is
# a valid cell or not
def isValid(x, y):
 
    if (x < R and y < C and x >= 0 and y >= 0):
        return True
 
    return False
 
# A function to mark all adjacent cells of
# landmines as unsafe. Landmines are shown with
# number 0
def findShortestPath(mat):
 
    for i in range(R):
        for j in range(C):
            # if a landmines is found
            if (mat[i][j] == 0):
                # mark all adjacent cells
                for k in range(4):
                    if (isValid(i + rowNum[k], j + colNum[k])):
                        mat[i + rowNum[k]][j + colNum[k]] = -1
             
    # mark all found adjacent cells as unsafe
    for i in range(R):
        for j in range(C):
            if (mat[i][j] == -1):
                mat[i][j] = 0
 
    dist = [[-1 for i in range(C)]for j in range(R)]
 
    q = []
 
    for i in range(R):
        if(mat[i][0] == 1):
            q.append(Key(i,0))
            dist[i][0] = 0
 
    while(len(q) != 0):
        k = q[0]
        q = q[1:]
 
        d = dist[k.x][k.y]
 
        x = k.x
        y = k.y
 
        for k in range(4):
            xp = x + rowNum[k]
            yp = y + colNum[k]
            if(isValid(xp,yp) and dist[xp][yp] == -1 and mat[xp][yp] == 1):
                dist[xp][yp] = d+1
                q.append(Key(xp,yp))
     
    # stores minimum cost of shortest path so far
    ans = sys.maxsize
 
    # start from first column and take minimum
    for i in range(R):
        if(mat[i][C-1] == 1 and dist[i][C-1] != -1):
            ans = min(ans,dist[i][C-1])
 
     
    # if destination can be reached
    if(ans == sys.maxsize):
        print("NOT POSSIBLE")
         
    else:  # if the destination is not reachable
        print(f"Length of shortest safe route is {ans}")
 
# Driver code
     
# input matrix with landmines shown with number 0
mat =[
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 ],
        [ 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ]
]
     
# find shortest path
findShortestPath(mat)
 
# This code is contributed by shinjanpatra

Javascript

<script>
 
// JavaScript program to find shortest safe Route in
// the matrix with landmines
const R = 12
const C = 10
 
class Key
{
    constructor(i, j)
    {
        this.x = i
        this.y = j
    }
}
 
// These arrays are used to get row and column
// numbers of 4 neighbours of a given cell
let rowNum = [ -1, 0, 0, 1 ]
let colNum = [ 0, -1, 1, 0 ]
 
// A function to check if a given cell (x, y) is
// a valid cell or not
function isValid(x, y)
{
    if (x < R && y < C && x >= 0 && y >= 0)
        return true
 
    return false
}
 
// A function to mark all adjacent cells of
// landmines as unsafe. Landmines are shown with
// number 0
function findShortestPath(mat){
    let i,j
 
    for (i = 0;i < R;i++)
    {
        for (j = 0;j < C;j++)
        {
            // if a landmines is found
            if (mat[i][j] == 0)
            {
            // mark all adjacent cells
            for (let k = 0;k < 4;k++)
                if (isValid(i + rowNum[k], j + colNum[k]))
                    mat[i + rowNum[k]][j + colNum[k]] = -1
            }
        }
    }
// mark all found adjacent cells as unsafe
    for (i = 0;i < R;i++)
    {
        for (j = 0;j < C;j++)
        {
            if (mat[i][j] == -1)
                mat[i][j] = 0
        }
    }
 
    let dist = new Array(R);
 
    for(i = 0; i < R; i++){
        dist[i] = new Array(C).fill(-1);
    }
    let q = [];
 
    for(i = 0; i < R; i++){
        if(mat[i][0] == 1){
            q.push(new Key(i,0))
            dist[i][0] = 0
        }
    }
 
    while(q.length != 0){
        let k = q.shift()
 
        let d = dist[k.x][k.y]
 
        let x = k.x
        let y = k.y
 
        for (let k = 0;k < 4;k++) {
            let xp = x + rowNum[k]
            let yp = y + colNum[k]
            if(isValid(xp,yp) && dist[xp][yp] == -1 && mat[xp][yp] == 1){
                dist[xp][yp] = d+1
                q.push(new Key(xp,yp))
            }
        }
    }
     
    // stores minimum cost of shortest path so far
    let ans = Number.MAX_VALUE
     
    // start from first column and take minimum
    for(let i = 0; i < R; i++)
    {
        if(mat[i][C-1] == 1 && dist[i][C-1] != -1){
            ans = Math.min(ans,dist[i][C-1])
        }
    }
     
    // if destination can be reached
    if(ans == Number.MAX_VALUE)
        document.write("NOT POSSIBLE","</br>")
         
    else  // if the destination is not reachable
        document.write("Length of shortest safe route is ",ans,"</br>")
}
 
// Driver code
     
// input matrix with landmines shown with number 0
let mat =[
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 0, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 0, 1, 1, 1, 1 ],
        [ 1, 0, 1, 1, 1, 1, 1, 1, 0, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 0, 1, 1, 1, 1, 0, 1, 1, 1, 1 ],
        [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ],
        [ 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 ]
]
     
// find shortest path
findShortestPath(mat)
 
// This code is contributed by shinjanpatra
 
</script>
Producción

Length of shortest safe route is 13

Este artículo es una contribución de Aditya Goel . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *