
- C++ Basics
- C++ Home
- C++ Overview
- C++ Environment Setup
- C++ Basic Syntax
- C++ Comments
- C++ Data Types
- C++ Variable Types
- C++ Variable Scope
- C++ Constants/Literals
- C++ Modifier Types
- C++ Storage Classes
- C++ Operators
- C++ Loop Types
- C++ Decision Making
- C++ Functions
- C++ Numbers
- C++ Arrays
- C++ Strings
- C++ Pointers
- C++ References
- C++ Date & Time
- C++ Basic Input/Output
- C++ Data Structures
- C++ Object Oriented
- C++ Classes & Objects
- C++ Inheritance
- C++ Overloading
- C++ Polymorphism
- C++ Abstraction
- C++ Encapsulation
- C++ Interfaces
Find shortest safe route in a path with landmines in C++
In this problem, we are given a matrix mat[][]. It defines a path with landmines which are marked as 0. Our task is to Find shortest safe route in a path with landmines.
While traversing through the safe path, we need to avoid walking adjacent cells of the landmine (left, right, above and bottom) for being unsafe.
All valid moves while traversing the path are −
- Left : mat[i][j] => mat[i-1][j] - Right : mat[i][j] => mat[i+1][j] - Top : mat[i][j] => mat[i][j - 1] - Bottom : mat[i][j] => mat[i][j + 1]
Let’s take an example to understand the problem,
Input
mat[][] = { {1, 1, 0, 1}, {1, 1, 0, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} }
Output
length of shortest safe path is 7
Explanation
{ {1, 1, 0, 1}, {1, 1, 0, 1}, {1, 1, 1, 1}, {1, 1, 1, 1} }
Solution Approach
A simple solution to the problem is using backtracking. But before finding the path to the solution, we will mark all the cells that are adjacent to a landmine as unsafe cells. Now, for starting cells in the First column, we will go to each cell that is safe from that position and then check if it leads to a destination (any cell in the last column) or not. Then for all safe positions that can lead to destination, find the shortest path to reach destination. If possible, return length of path
Else return -1, denoting no path found
Program to illustrate the working of our solution,
Example
#include <bits/stdc++.h> using namespace std; #define R 11 #define C 10 int rowNum[] = { -1, 0, 0, 1 }; int colNum[] = { 0, -1, 1, 0 }; bool isSafe(int mat[R][C], int isvisited[R][C], int x, int y){ if (mat[x][y] == 0 || isvisited[x][y]) return false; return true; } bool isValid(int x, int y){ if (x < R && y < C && x >= 0 && y >= 0) return true; return false; } void unSafeCellsInPath(int mat[R][C]){ for (int i = 0; i < R; i++){ for (int j = 0; j < C; j++){ if (mat[i][j] == 0){ for (int k = 0; k < 4; k++) if (isValid(i + rowNum[k], j + colNum[k])) mat[i + rowNum[k]][j + colNum[k]] = -1; } } } for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++){ if (mat[i][j] == -1) mat[i][j] = 0; } } } void findShortestSafeRouteRec(int mat[R][C], int isvisited[R][C], int i, int j, int &min_dist, int dist){ if (j == C-1){ min_dist = min(dist, min_dist); return; } if (dist > min_dist) return; isvisited[i][j] = 1; for (int k = 0; k < 4; k++){ if (isValid(i + rowNum[k], j + colNum[k]) && isSafe(mat, isvisited, i + rowNum[k], j + colNum[k])){ findShortestSafeRouteRec(mat, isvisited, i + rowNum[k], j + colNum[k], min_dist, dist + 1); } } isvisited[i][j] = 0; } int findShortestSafeRoute(int mat[R][C]){ int minSafeDist = INT_MAX; int isvisited[R][C]; unSafeCellsInPath(mat); for (int i = 0; i < R; i++) { if (mat[i][0] == 1) { memset(isvisited, 0, sizeof isvisited); findShortestSafeRouteRec(mat, isvisited, i, 0, minSafeDist, 0); if(minSafeDist == C - 1) break; } } if (minSafeDist != INT_MAX) return minSafeDist; else return -1; } int main() { int mat[R][C] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 0, 1, 1, 1, 1, 1, 1, 0, 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, 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, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 } }; int pathLen = findShortestSafeRoute(mat); if(pathLen == -1) cout<<"No Safe Path from source to destination possible!"; else cout<<"Shortest Safe route Length is "<<pathLen; return 0; }
Output
Shortest Safe route Length is 10
Alternate solution
An alternate solution to the problem is using breadth first search. Using the queue, we will find the path from first column to last column and then return the minimum distance for the path from first column to last column.
Program to illustrate the working of our solution,
Example
#include <bits/stdc++.h> using namespace std; #define R 11 #define C 10 int rowNum[] = { -1, 0, 0, 1 }; int colNum[] = { 0, -1, 1, 0 }; struct Key{ int x,y; Key(int i,int j){ x=i;y=j;}; }; bool isValid(int x, int y) { if (x < R && y < C && x >= 0 && y >= 0) return true; return false; } int findShortestSafeRoute(int mat[R][C]){ for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { if (mat[i][j] == 0) { for (int k = 0; k < 4; k++) if (isValid(i + rowNum[k], j + colNum[k])) mat[i + rowNum[k]][j + colNum[k]] = -1; } } } for (int i = 0; i < R; i++) { for (int j = 0; j < C; j++) { if (mat[i][j] == -1) mat[i][j] = 0; } } int visited[R][C]; for(int i=0;i<R;i++){ for(int j=0;j<C;j++) visited[i][j] = -1; } queue<Key> distQueue; for(int i=0;i<R;i++){ if(mat[i][0] == 1){ distQueue.push(Key(i,0)); visited[i][0] = 0; } } while(!distQueue.empty()){ Key k = distQueue.front(); distQueue.pop(); int d = visited[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) && visited[xp][yp] == -1 && mat[xp][yp] == 1){ visited[xp][yp] = d+1; distQueue.push(Key(xp,yp)); } } } int pathLen = INT_MAX; for(int i=0;i<R;i++){ if(mat[i][C-1] == 1 && visited[i][C-1] != -1){ pathLen = min(pathLen,visited[i][C-1]); } } if(pathLen == INT_MAX) return -1; else return pathLen; } int main() { int mat[R][C] = { { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 0, 1, 1, 1, 1, 1, 1, 0, 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, 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, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 0, 1, 1 }, { 1, 1, 1, 0, 1, 1, 1, 1, 1, 1 } }; int pathLen = findShortestSafeRoute(mat); if(pathLen == -1) cout<<"No Safe Path from source to destination possible!"; else cout<<"Shortest Safe route Length is "<<pathLen; return 0; }
Output
Shortest Safe route Length is 10
- Related Articles
- Shortest Path with Alternating Colors in Python
- Shortest Path in a Grid with Obstacles Elimination in C++
- Shortest path with exactly k Edges
- Shortest path algorithms in Javascript
- Shortest Path in a Directed Acyclic Graph
- Shortest Path algorithm in Computer Network
- Shortest Path in Binary Matrix in C++
- Dijkstra’s Shortest Path Algorithm
- Shortest Path Visiting All Nodes in C++
- Shortest Path to Get All Keys in C++
- Program to find out the shortest path to reach the goal in Python
- What is the Shortest Path Routing in Computer Network?
- C++ program to find out the shortest cost path in a given graph for q queries
- C++ Program to Find SSSP (Single Source Shortest Path) in DAG (Directed Acyclic Graphs)
- Print shortest path to print a string on screen in C Program.
