给定大小为M * N的网格mat [] [] ,它仅由0 s, 1 s和2 s组成,其中0代表空的地方, 1代表一个人, 2代表火,任务是计算最小值使人员安全离开网格所需的移动次数。在每一步中,火都将燃烧其旁边相邻的牢房,人员将从当前牢房移到其旁边相邻的牢房之一。如果不可能从网格中出来,则打印-1 。
注意:如果某人到达网格的边界之一,则该人将从网格中出来。
例子:
Input: mat[][] = { { 0, 0, 0, 0 }, { 2, 0, 0, 0 }, { 2, 1, 0, 0 }, { 2, 2, 0, 0 } }
Output: 2
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
方法:可以使用概念解决烂橙的问题来解决该问题。这个想法是在蔓延的火势以及人的移动上执行BFS。请按照以下步骤解决问题:
- 初始化两个空队列fQ和pQ ,分别存储火可以蔓延和人员可以移动到的单元。
- 初始化一个2D数组,例如Visited [] [] ,以检查人员是否已经访问了单元格(i,j) 。
- 排队人员的所有侧面相邻单元,并将所有相邻单元标记为已访问单元。
- 将火力电池的所有相邻边电池放入fQ中,并将所有边相邻的电池标记为燃烧电池。
- 初始化一个变量,例如depth ,以跟踪两个像元之间的最短距离。
- 当pQ不为空时,请执行以下步骤:
- 将深度增加1。
- 将所有单元格从pQ移出,并排入弹出单元格的所有有效侧边相邻单元格。
- 如果网格的边界处有任何相邻的被排队的像元,则打印depth的值。
- 否则,将所有单元从fQ出队。对于每个弹出的单元,将所有有效的相邻单元排入队列。
- 通过以上步骤,如果无法从网格中出来,请打印-1 。
下面是上述方法的实现:
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[0].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(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 pos = pQ.front();
// Remove front element of
// the queue pQ
pQ.pop();
// If cuurent 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 (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.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 (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 cuurent 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 cuurent 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 cuurent 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
2
时间复杂度: O(N * M)
辅助空间: O(N * M)