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>
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>
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