 Open in App
Not now

# Minimum moves required to come out of a grid safely

• Difficulty Level : Hard
• Last Updated : 16 Jul, 2021

Given a grid mat[][] of size M * N, consisting of only 0s, 1s, and 2s, where 0 represents empty place, 1 represents a person and 2 represents the fire, the task is to count the minimum number of moves required such that the person comes out from the grid safely. In each step, the fire will burn its side-adjacent cells and the person will move from the current cell to one of its side-adjacent cells. If it is not possible to come out from the grid, then print -1.

Note: A person will come out from the grid if the person reaches one of the border sides of the grid.

Examples:

Input: mat[][] = { { 0, 0, 0, 0 }, { 2, 0, 0, 0 }, { 2, 1, 0, 0 }, { 2, 2, 0, 0 } }
Output:
Explanation:
Possible moves of the person are (2, 1) → (2, 2) → (2, 3).
The person reaches one of the border sides of the grid(last row) in 2 moves and also it is the minimum possible count.
Therefore, the required output is 2.

Input: mat[][] = { { 0, 2, 0, 0 }, { 2, 1, 0, 2 }, { 2, 0, 0, 0 }, { 2, 0, 2, 0 }}
Output: -1

Approach: The problem can be solved using concepts to solve the problem Rotten Oranges. The idea is to perform BFS on the spreading fire as well as the moves of the person. Follow the steps below to solve the problem:

1. Initialize two empty queues fQ and pQ, to store the cellsin which the fire can spread and the person can move to, respectively.
2. Initialize a 2D array, say visited[][], to check if the cell (i, j) is already visited by the person or not.
3. Enqueue all the side-adjacent cells of the person and mark all the adjacent cells as visited cell.
4. Enqueue all the side-adjacent cells of the fire cells into fQ and mark all the side-adjacent cells as burning cells.
5. Initialize a variable, say depth, to keep track of the shortest distance between two cells.
6. Perform the following steps while pQ is not empty:
• Increment the depth by 1.
• Dequeue all cells from pQ and enqueue all the valid side-adjacent cells of the popped cell.
• If any adjacent cell enqueued is present at border of the grid, then print the value of depth.
• Otherwise, dequeue all the cells from fQ. For each popped cell, enqueue all the valid adjacent cells.
7. From the above steps, if it is not possible to come out from the grid, then print -1.

Below is the implementation of above approach:

## C++

 `// C++ program to implement``// the above approach` `#include ` `using` `namespace` `std;` `// Stores size of the grid``int` `m, n;` `// Function to check valid``// cells of the grid``bool` `valid(``int` `x, ``int` `y)``{``    ``return` `(x >= 0 && x < m && y >= 0 && y < n);``}` `// Checks for the border sides``bool` `border(``int` `x, ``int` `y)``{``    ``return` `(x == 0 || x == m - 1 || y == 0 || y == n - 1);``}`  `// Function to find shortest distance``// between two cells of the grid``int` `minStep(vector> mat)``{` `    ``// Rows of the grid``    ``m = mat.size();` `    ``// Column of the grid``    ``n = mat.size();` `    ``// Stores possible move``    ``// of the person``    ``int` `dx[] = { 1, -1, 0, 0 };``    ``int` `dy[] = { 0, 0, 1, -1 };` `    ``// Store possible cells visited``    ``// by the person``    ``queue > pQ;` `    ``// Store possible cells which``    ``// are burning``    ``queue > fQ;` `    ``// Traverse the grid``    ``for` `(``int` `i = 0; i < m; i++){` `        ``for` `(``int` `j = 0; j < n; j++) {` `            ``// If current cell is``            ``// burning``            ``if` `(mat[i][j] == 2)``                ``fQ.push({i, j});``            ``// If person is in``            ``// the current cell``            ``else` `if` `(mat[i][j] == 1) {``                ``if` `(border(i, j))``                    ``return` `0;``                ``pQ.push({i, j});``            ``}``        ``}``    ``}``    ``// Stores shortest distance``    ``// between two cells``    ``int` `depth = 0;` `    ``// Check if a cell is visited``    ``// by the person or not``    ``vector> visited(n,vector<``int``>(m,0));` `    ``// While pQ is not empty``    ``while` `(pQ.size()>0) {` `        ``// Update depth``        ``depth++;` `        ``// Popped all the cells from``        ``// pQ and mark all adjacent cells``        ``// of as visited``        ``for` `(``int` `i = pQ.size(); i > 0;i--) {` `            ``// Front element of``            ``// the queue pQ``            ``pair<``int``,``int``>  pos = pQ.front();` `            ``// Remove front element of``            ``// the queue pQ``            ``pQ.pop();` `            ``// If current cell is burning``            ``if` `(mat[pos.first][pos.second] == 2)``                ``continue``;` `            ``// Find all adjacent cells``            ``for` `(``int` `j = 0; j < 4; j++) {` `                ``// Stores row number of``                ``// adjacent cell``                ``int` `x = pos.first + dx[j];` `                ``// Stores column number``                ``// of adjacent cell``                ``int` `y = pos.second + dy[j];` `                ``// Checks if current cell``                ``// is valid``                ``if` `(valid(x, y) && mat[x][y] != 2 && !visited[x][y]) {` `                    ``// Mark the cell as visited``                    ``visited[x][y] = 1;` `                    ``// Enqueue the cell``                    ``pQ.push(pair<``int``,``int``> (x, y));` `                    ``// Checks the escape condition``                    ``if` `(border(x, y))``                        ``return` `depth;``                ``}``            ``}``        ``}` `        ``// Burn all the adjacent cells``        ``// of burning cells``        ``for` `(``int` `i = fQ.size(); i > 0; i--) {` `            ``// Front element of``            ``// the queue fQ``            ``pair<``int``,``int``>  pos = fQ.front();` `            ``// Delete front element of``            ``// the queue fQ``            ``fQ.pop();` `            ``// Find adjacent cells of``            ``// burning cell``            ``for` `(``int` `j = 0; j < 4; j++) {` `                ``// Stores row number of``                ``// adjacent cell``                ``int` `x = pos.first + dx[j];` `                ``// Stores column number``                ``// of adjacent cell``                ``int` `y = pos.second + dy[j];` `                ``// Checks if current``                ``// cell is valid``                ``if` `(valid(x, y) && mat[x][y] != 2) {` `                    ``mat[x][y] = 2;` `                    ``// Burn all the adjacent``                    ``// cells of current cell``                    ``fQ.push(pair<``int``,``int``> (x, y));``                ``}``            ``}``        ``}``    ``}``    ``return` `-1;``}` `// Driver Code``int` `main()``{` `    ``// Given grid``    ``vector> grid = { { 0, 0, 0, 0 },``                     ``{ 2, 0, 0, 0 },``                     ``{ 2, 1, 0, 0 },``                     ``{ 2, 2, 0, 0 } };` `    ``cout<

## Java

 `// Java program to implement``// the above approach``import` `java.util.*;``import` `java.lang.*;``class` `GFG``{` `    ``// Structure of cell``    ``// of the grid``    ``static` `class` `pair``    ``{``        ``int` `x, y;``        ``pair(``int` `x, ``int` `y)``        ``{``            ``this``.x = x;``            ``this``.y = y;``        ``}``    ``}` `    ``// Stores size of the grid``    ``static` `int` `m, n;` `    ``// Function to find shortest distance``    ``// between two cells of the grid``    ``static` `int` `minStep(``int``[][] mat)``    ``{` `        ``// Rows of the grid``        ``m = mat.length;` `        ``// Column of the grid``        ``n = mat[``0``].length;` `        ``// Stores possible move``        ``// of the person``        ``int` `dx[] = { ``1``, -``1``, ``0``, ``0` `};``        ``int` `dy[] = { ``0``, ``0``, ``1``, -``1` `};` `        ``// Store possible cells visited``        ``// by the person``        ``Queue pQ = ``new` `LinkedList<>();` `        ``// Store possible cells which``        ``// are burning``        ``Queue fQ = ``new` `LinkedList<>();` `        ``// Traverse the grid``        ``for` `(``int` `i = ``0``; i < m; i++)``            ``for` `(``int` `j = ``0``; j < n; j++)``            ``{` `                ``// If current cell is``                ``// burning``                ``if` `(mat[i][j] == ``2``)``                    ``fQ.add(``new` `pair(i, j));` `                ``// If person is in``                ``// the current cell``                ``else` `if` `(mat[i][j] == ``1``)``                ``{``                    ``if` `(border(i, j))``                        ``return` `0``;``                    ``pQ.add(``new` `pair(i, j));``                ``}``            ``}` `        ``// Stores shortest distance``        ``// between two cells``        ``int` `depth = ``0``;` `        ``// Check if a cell is visited``        ``// by the person or not``        ``boolean``[][] visited``            ``= ``new` `boolean``[n][m];` `        ``// While pQ is not empty``        ``while` `(!pQ.isEmpty())``        ``{` `            ``// Update depth``            ``depth++;` `            ``// Popped all the cells from``            ``// pQ and mark all adjacent cells``            ``// of as visited``            ``for` `(``int` `i = pQ.size(); i > ``0``; i--)``            ``{` `                ``// Front element of``                ``// the queue pQ``                ``pair pos = pQ.peek();` `                ``// Remove front element of``                ``// the queue pQ``                ``pQ.remove();` `                ``// If current cell is burning``                ``if` `(mat[pos.x][pos.y] == ``2``)``                    ``continue``;` `                ``// Find all adjacent cells``                ``for` `(``int` `j = ``0``; j < ``4``; j++)``                ``{` `                    ``// Stores row number of``                    ``// adjacent cell``                    ``int` `x = pos.x + dx[j];` `                    ``// Stores column number``                    ``// of adjacent cell``                    ``int` `y = pos.y + dy[j];` `                    ``// Checks if current cell``                    ``// is valid``                    ``if` `(valid(x, y) && mat[x][y] != ``2``                        ``&& !visited[x][y])``                    ``{` `                        ``// Mark the cell as visited``                        ``visited[x][y] = ``true``;` `                        ``// Enqueue the cell``                        ``pQ.add(``new` `pair(x, y));` `                        ``// Checks the escape condition``                        ``if` `(border(x, y))``                            ``return` `depth;``                    ``}``                ``}``            ``}` `            ``// Burn all the adjacent cells``            ``// of burning cells``            ``for` `(``int` `i = fQ.size(); i > ``0``; i--)``            ``{` `                ``// Front element of``                ``// the queue fQ``                ``pair pos = fQ.peek();` `                ``// Delete front element of``                ``// the queue fQ``                ``fQ.remove();` `                ``// Find adjacent cells of``                ``// burning cell``                ``for` `(``int` `j = ``0``; j < ``4``; j++)``                ``{` `                    ``// Stores row number of``                    ``// adjacent cell``                    ``int` `x = pos.x + dx[j];` `                    ``// Stores column number``                    ``// of adjacent cell``                    ``int` `y = pos.y + dy[j];` `                    ``// Checks if current``                    ``// cell is valid``                    ``if` `(valid(x, y) && mat[x][y] != ``2``)``                    ``{` `                        ``mat[x][y] = ``2``;` `                        ``// Burn all the adjacent``                        ``// cells of current cell``                        ``fQ.add(``new` `pair(x, y));``                    ``}``                ``}``            ``}``        ``}``        ``return` `-``1``;``    ``}` `    ``// Function to check valid``    ``// cells of the grid``    ``static` `boolean` `valid(``int` `x, ``int` `y)``    ``{``        ``return` `(x >= ``0` `&& x < m``                ``&& y >= ``0` `&& y < n);``    ``}` `    ``// Checks for the border sides``    ``static` `boolean` `border(``int` `x, ``int` `y)``    ``{``        ``return` `(x == ``0` `|| x == m - ``1``                ``|| y == ``0` `|| y == n - ``1``);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `main(String[] args)``    ``{` `        ``// Given grid``        ``int``[][] grid = { { ``0``, ``0``, ``0``, ``0` `},``                         ``{ ``2``, ``0``, ``0``, ``0` `},``                         ``{ ``2``, ``1``, ``0``, ``0` `},``                         ``{ ``2``, ``2``, ``0``, ``0` `} };` `        ``System.out.println(minStep(grid));``    ``}``}` `// This code is contributed by mohit kumar 29.`

## Python3

 `# Python3 program to implement``# the above approach` `# Stores size of the grid``m ``=` `0``n ``=` `0` `# Function to check valid``# cells of the grid``def` `valid(x, y):``    ` `    ``global` `n``    ``global` `m``    ``return` `(x >``=` `0` `and` `x < m ``and``            ``y >``=` `0` `and` `y < n)` `# Checks for the border sides``def` `border(x, y):``    ` `    ``global` `n``    ``global` `m``    ``return` `(x ``=``=` `0` `or` `x ``=``=` `m ``-` `1` `or``            ``y ``=``=` `0` `or` `y ``=``=` `n ``-` `1``)` `# Function to find shortest distance``# between two cells of the grid``def` `minStep(mat):``    ` `    ``global` `n``    ``global` `m``    ` `    ``# Rows of the grid``    ``m ``=` `len``(mat)` `    ``# Column of the grid``    ``n ``=` `len``(mat[``0``])` `    ``# Stores possible move``    ``# of the person``    ``dx ``=` `[``1``, ``-``1``, ``0``, ``0``]``    ``dy ``=` `[``0``, ``0``, ``1``, ``-``1``]` `    ``# Store possible cells visited``    ``# by the person``    ``pQ ``=` `[]` `    ``# Store possible cells which``    ``# are burning``    ``fQ ``=` `[]` `    ``# Traverse the grid``    ``for` `i ``in` `range``(m):``        ``for` `j ``in` `range``(n):``            ` `            ``# If current cell is``            ``# burning``            ``if` `(mat[i][j] ``=``=` `2``):``                ``fQ.append([i, j])``                ` `            ``# If person is in``            ``# the current cell``            ``elif``(mat[i][j] ``=``=` `1``):``                ``if` `(border(i, j)):``                    ``return` `0``                    ` `                ``pQ.append([i, j])` `    ``# Stores shortest distance``    ``# between two cells``    ``depth ``=` `0` `    ``# Check if a cell is visited``    ``# by the person or not``    ``visited ``=` `[[``0` `for` `i ``in` `range``(m)]``                  ``for` `j ``in` `range``(n)]` `    ``# While pQ is not empty``    ``while` `(``len``(pQ) > ``0``):``        ` `        ``# Update depth``        ``depth ``+``=` `1` `        ``# Popped all the cells from``        ``# pQ and mark all adjacent cells``        ``# of as visited``        ``i ``=` `len``(pQ)``        ` `        ``while``(i > ``0``):``            ` `            ``# Front element of``            ``# the queue pQ``            ``pos ``=` `pQ[``0``]` `            ``# Remove front element of``            ``# the queue pQ``            ``pQ.remove(pQ[``0``])` `            ``# If current cell is burning``            ``if` `(mat[pos[``0``]][pos[``1``]] ``=``=` `2``):``                ``continue` `            ``# Find all adjacent cells``            ``for` `j ``in` `range``(``4``):``                ` `                ``# Stores row number of``                ``# adjacent cell``                ``x ``=` `pos[``0``] ``+` `dx[j]` `                ``# Stores column number``                ``# of adjacent cell``                ``y ``=` `pos[``1``] ``+` `dy[j]` `                ``# Checks if current cell``                ``# is valid``                ``if` `(valid(x, y) ``and` `mat[x][y] !``=` `2` `and``                    ``visited[x][y] ``=``=` `0``):` `                    ``# Mark the cell as visited``                    ``visited[x][y] ``=` `1` `                    ``# Enqueue the cell``                    ``pQ.append([x, y])` `                    ``# Checks the escape condition``                    ``if` `(border(x, y)):``                        ``return` `depth``                        ` `            ``i ``-``=` `1` `        ``# Burn all the adjacent cells``        ``# of burning cells``        ``i ``=` `len``(fQ)``        ` `        ``while``(i > ``0``):` `            ``# Front element of``            ``# the queue fQ``            ``pos ``=` `fQ[``0``]` `            ``# Delete front element of``            ``# the queue fQ``            ``fQ.remove(fQ[``0``])` `            ``# Find adjacent cells of``            ``# burning cell``            ``for` `j ``in` `range``(``4``):``                ` `                ``# Stores row number of``                ``# adjacent cell``                ``x ``=` `pos[``0``] ``+` `dx[j]` `                ``# Stores column number``                ``# of adjacent cell``                ``y ``=` `pos[``1``] ``+` `dy[j]` `                ``# Checks if current``                ``# cell is valid``                ``if` `(valid(x, y) ``and` `mat[x][y] !``=` `2``):``                    ``mat[x][y] ``=` `2` `                    ``# Burn all the adjacent``                    ``# cells of current cell``                    ``fQ.append([x, y])``                    ` `            ``i ``-``=` `1` `    ``return` `-``1` `# Driver Code``if` `__name__ ``=``=` `'__main__'``:``    ` `    ``# Given grid``    ``grid ``=` `[ [ ``0``, ``0``, ``0``, ``0` `],``             ``[ ``2``, ``0``, ``0``, ``0` `],``             ``[ ``2``, ``1``, ``0``, ``0` `],``             ``[ ``2``, ``2``, ``0``, ``0` `] ]` `    ``print``(minStep(grid))` `# This code is contributed by SURENDRA_GANGWAR`

## C#

 `// C# program to implement``// the above approach``using` `System;``using` `System.Collections.Generic;``public` `class` `GFG``{` `  ``// Structure of cell``  ``// of the grid``  ``class` `pair``  ``{``    ``public` `int` `x, y;``    ``public` `pair(``int` `x, ``int` `y)``    ``{``      ``this``.x = x;``      ``this``.y = y;``    ``}``  ``}` `  ``// Stores size of the grid``  ``static` `int` `m, n;` `  ``// Function to find shortest distance``  ``// between two cells of the grid``  ``static` `int` `minStep(``int``[,] mat)``  ``{` `    ``// Rows of the grid``    ``m = mat.GetLength(0);` `    ``// Column of the grid``    ``n = mat.GetLength(1);` `    ``// Stores possible move``    ``// of the person``    ``int` `[]dx = { 1, -1, 0, 0 };``    ``int` `[]dy = { 0, 0, 1, -1 };` `    ``// Store possible cells visited``    ``// by the person``    ``Queue pQ = ``new` `Queue();` `    ``// Store possible cells which``    ``// are burning``    ``Queue fQ = ``new` `Queue();` `    ``// Traverse the grid``    ``for` `(``int` `i = 0; i < m; i++)``      ``for` `(``int` `j = 0; j < n; j++)``      ``{` `        ``// If current cell is``        ``// burning``        ``if` `(mat[i, j] == 2)``          ``fQ.Enqueue(``new` `pair(i, j));` `        ``// If person is in``        ``// the current cell``        ``else` `if` `(mat[i, j] == 1)``        ``{``          ``if` `(border(i, j))``            ``return` `0;``          ``pQ.Enqueue(``new` `pair(i, j));``        ``}``      ``}` `    ``// Stores shortest distance``    ``// between two cells``    ``int` `depth = 0;` `    ``// Check if a cell is visited``    ``// by the person or not``    ``bool``[,] visited``      ``= ``new` `bool``[n, m];` `    ``// While pQ is not empty``    ``while` `(pQ.Count != 0)``    ``{` `      ``// Update depth``      ``depth++;` `      ``// Popped all the cells from``      ``// pQ and mark all adjacent cells``      ``// of as visited``      ``for` `(``int` `i = pQ.Count; i > 0; i--)``      ``{` `        ``// Front element of``        ``// the queue pQ``        ``pair pos = pQ.Peek();` `        ``// Remove front element of``        ``// the queue pQ``        ``pQ.Dequeue();` `        ``// If current cell is burning``        ``if` `(mat[pos.x, pos.y] == 2)``          ``continue``;` `        ``// Find all adjacent cells``        ``for` `(``int` `j = 0; j < 4; j++)``        ``{` `          ``// Stores row number of``          ``// adjacent cell``          ``int` `x = pos.x + dx[j];` `          ``// Stores column number``          ``// of adjacent cell``          ``int` `y = pos.y + dy[j];` `          ``// Checks if current cell``          ``// is valid``          ``if` `(valid(x, y) && mat[x, y] != 2``              ``&& !visited[x, y])``          ``{` `            ``// Mark the cell as visited``            ``visited[x, y] = ``true``;` `            ``// Enqueue the cell``            ``pQ.Enqueue(``new` `pair(x, y));` `            ``// Checks the escape condition``            ``if` `(border(x, y))``              ``return` `depth;``          ``}``        ``}``      ``}` `      ``// Burn all the adjacent cells``      ``// of burning cells``      ``for` `(``int` `i = fQ.Count; i > 0; i--)``      ``{` `        ``// Front element of``        ``// the queue fQ``        ``pair pos = fQ.Peek();` `        ``// Delete front element of``        ``// the queue fQ``        ``fQ.Dequeue();` `        ``// Find adjacent cells of``        ``// burning cell``        ``for` `(``int` `j = 0; j < 4; j++)``        ``{` `          ``// Stores row number of``          ``// adjacent cell``          ``int` `x = pos.x + dx[j];` `          ``// Stores column number``          ``// of adjacent cell``          ``int` `y = pos.y + dy[j];` `          ``// Checks if current``          ``// cell is valid``          ``if` `(valid(x, y) && mat[x, y] != 2)``          ``{` `            ``mat[x, y] = 2;` `            ``// Burn all the adjacent``            ``// cells of current cell``            ``fQ.Enqueue(``new` `pair(x, y));``          ``}``        ``}``      ``}``    ``}``    ``return` `-1;``  ``}` `  ``// Function to check valid``  ``// cells of the grid``  ``static` `bool` `valid(``int` `x, ``int` `y)``  ``{``    ``return` `(x >= 0 && x < m``            ``&& y >= 0 && y < n);``  ``}` `  ``// Checks for the border sides``  ``static` `bool` `border(``int` `x, ``int` `y)``  ``{``    ``return` `(x == 0 || x == m - 1``            ``|| y == 0 || y == n - 1);``  ``}` `  ``// Driver Code``  ``public` `static` `void` `Main(String[] args)``  ``{` `    ``// Given grid``    ``int``[,] grid = { { 0, 0, 0, 0 },``                   ``{ 2, 0, 0, 0 },``                   ``{ 2, 1, 0, 0 },``                   ``{ 2, 2, 0, 0 } };` `    ``Console.WriteLine(minStep(grid));``  ``}``}` `// This code is contributed by shikhasingrajput`

## Javascript

 ``

Output:

`2`

Time Complexity: O(N * M)
Auxiliary Space: O(N * M)

My Personal Notes arrow_drop_up