📜  在银行中找到与守卫的最短距离

📅  最后修改于: 2022-05-13 01:57:23.403000             🧑  作者: Mango

在银行中找到与守卫的最短距离

给定一个由“O”、“G”和“W”填充的矩阵,其中“O”代表开放空间,“G”代表守卫,“W”代表银行的墙壁。将矩阵中的所有 O 替换为与守卫的最短距离,而不能穿过任何墙壁。此外,在输出矩阵中用 0 替换守卫,用 -1 替换墙壁。
M x N 矩阵的预期时间复杂度为 O(MN)。

例子:

O ==> Open Space
G ==> Guard
W ==> Wall

Input: 
  O  O  O  O  G
  O  W  W  O  O
  O  O  O  W  O
  G  W  W  W  O
  O  O  O  O  G

Output:  
  3  3  2  1  0
  2 -1 -1  2  1
  1  2  3 -1  2
  0 -1 -1 -1  1
  1  2  2  1  0

这个想法是做BFS。我们首先将所有包含警卫的单元排入队列并循环直到队列不为空。对于循环的每次迭代,我们将前面的单元格从队列中取出,对于它的四个相邻单元格中的每一个,如果单元格是一个开放区域并且尚未计算它与守卫的距离,我们会更新它的距离并将其入队。最后在 BFS 过程结束后,我们打印距离矩阵。

以下是上述想法的实现 -

C++
// C++ program to replace all of the O's in the matrix
// with their shortest distance from a guard
#include 
using namespace std;
 
// store dimensions of the matrix
#define M 5
#define N 5
 
// An Data Structure for queue used in BFS
struct queueNode
{
    // i, j and distance stores x and y-coordinates
    // of a matrix cell and its distance from guard
    // respectively
    int i, j, distance;
};
 
// These arrays are used to get row and column
// numbers of 4 neighbors of a given cell
int row[] = { -1, 0, 1, 0};
int col[] = { 0, 1, 0, -1 };
 
// return true if row number and column number
// is in range
bool isValid(int i, int j)
{
    if ((i < 0 || i > M - 1) || (j < 0 || j > N - 1))
        return false;
 
    return true;
}
 
// return true if current cell is an open area and its
// distance from guard is not calculated yet
bool isSafe(int i, int j, char matrix[][N], int output[][N])
{
    if (matrix[i][j] != 'O' || output[i][j] != -1)
        return false;
 
    return true;
}
 
// Function to replace all of the O's in the matrix
// with their shortest distance from a guard
void findDistance(char matrix[][N])
{
    int output[M][N];
    queue q;
 
    // finding Guards location and adding into queue
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            // initialize each cell as -1
            output[i][j] = -1;
            if (matrix[i][j] == 'G')
            {
                queueNode pos = {i, j, 0};
                q.push(pos);
                // guard has 0 distance
                output[i][j] = 0;
            }
        }
    }
 
    // do till queue is empty
    while (!q.empty())
    {
        // get the front cell in the queue and update
        // its adjacent cells
        queueNode curr = q.front();
        int x = curr.i, y = curr.j, dist = curr.distance;
 
        // do for each adjacent cell
        for (int i = 0; i < 4; i++)
        {
            // if adjacent cell is valid, has path and
            // not visited yet, en-queue it.
            if (isSafe(x + row[i], y + col[i], matrix, output)
                && isValid(x + row[i], y + col[i]))
            {
                output[x + row[i]][y + col[i]] = dist + 1;
 
                queueNode pos = {x + row[i], y + col[i], dist + 1};
                q.push(pos);
            }
        }
 
        // dequeue the front cell as its distance is found
        q.pop();
    }
 
    // print output matrix
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
            cout << std::setw(3) << output[i][j];
        cout << endl;
    }
}
 
// Driver code
int main()
{
    char matrix[][N] =
    {
        {'O', 'O', 'O', 'O', 'G'},
        {'O', 'W', 'W', 'O', 'O'},
        {'O', 'O', 'O', 'W', 'O'},
        {'G', 'W', 'W', 'W', 'O'},
        {'O', 'O', 'O', 'O', 'G'}
    };
 
    findDistance(matrix);
 
    return 0;
}


Java
// Java program to replace all of the O's
// in the matrix with their shortest
// distance from a guard
package Graphs;
 
import java.util.LinkedList;
import java.util.Queue;
 
public class MinDistanceFromaGuardInBank{
     
// Store dimensions of the matrix
int M = 5;
int N = 5;
 
class Node
{
    int i, j, dist;
    Node(int i, int j, int dist)
    {
        this.i = i;
        this.j = j;
        this.dist = dist;
    }
}
 
// These arrays are used to get row
// and column numbers of 4 neighbors
// of a given cell
int row[] = { -1, 0, 1, 0 };
int col[] = { 0, 1, 0, -1 };
 
// Return true if row number and
// column number is in range
boolean isValid(int i, int j)
{
    if ((i < 0 || i > M - 1) ||
        (j < 0 || j > N - 1))
        return false;
 
    return true;
}
 
// Return true if current cell is
// an open area and its distance
// from guard is not calculated yet
boolean isSafe(int i, int j, char matrix[][],
                              int output[][])
{
    if (matrix[i][j] != 'O' ||
        output[i][j] != -1)
        return false;
         
    return true;
}
 
// Function to replace all of the O's
// in the matrix with their shortest
// distance from a guard
void findDistance(char matrix[][])
{
    int output[][] = new int[M][N];
    Queue q = new LinkedList();
     
    // Finding Guards location and
    // adding into queue
    for(int i = 0; i < M; i++)
    {
        for(int j = 0; j < N; j++)
        {
             
            // Initialize each cell as -1
            output[i][j] = -1;
             
            if (matrix[i][j] == 'G')
            {
                q.add(new Node(i, j, 0));
                 
                // Guard has 0 distance
                output[i][j] = 0;
            }
        }
    }
     
    // Do till queue is empty
    while (!q.isEmpty())
    {
         
        // Get the front cell in the queue
        // and update its adjacent cells
        Node curr = q.peek();
        int x = curr.i;
        int y = curr.j;
        int dist = curr.dist;
         
        // Do for each adjacent cell
        for (int i = 0; i < 4; i++)
        {
             
            // If adjacent cell is valid, has
            // path and not visited yet,
            // en-queue it.
            if (isValid(x + row[i], y + col[i]))
            {
                if (isSafe(x + row[i], y + col[i],
                           matrix, output))
                {
                    output[x + row[i]][y + col[i]] = dist + 1;
                    q.add(new Node(x + row[i],
                                   y + col[i],
                                   dist + 1));
                }
            }
        }
         
        // Dequeue the front cell as
        // its distance is found
        q.poll();
    }
     
    // Print output matrix
    for(int i = 0; i < M; i++)
    {
        for(int j = 0; j < N; j++)
        {
            System.out.print(output[i][j] + " ");
        }
        System.out.println();
    }
}
 
// Driver code
public static void main(String args[])
{
    char matrix[][] = { { 'O', 'O', 'O', 'O', 'G' },
                        { 'O', 'W', 'W', 'O', 'O' },
                        { 'O', 'O', 'O', 'W', 'O' },
                        { 'G', 'W', 'W', 'W', 'O' },
                        { 'O', 'O', 'O', 'O', 'G' } };
                         
    MinDistanceFromaGuardInBank g =
    new MinDistanceFromaGuardInBank();
     
    g.findDistance(matrix);
}
}
 
// This code is contributed by Shobhit Yadav


Python3
# Python3 program to replace all of the O's in the matrix
# with their shortest distance from a guard
from collections import deque as queue
 
# store dimensions of the matrix
M = 5
N = 5
 
 
# These arrays are used to get row and column
# numbers of 4 neighbors of a given cell
row = [-1, 0, 1, 0]
col = [0, 1, 0, -1]
 
# return true if row number and column number
# is in range
def isValid(i, j):
    if ((i < 0 or i > M - 1) or (j < 0 or j > N - 1)):
        return False
 
    return True
 
# return true if current cell is an open area and its
# distance from guard is not calculated yet
def isSafe(i, j,matrix, output):
 
    if (matrix[i][j] != 'O' or output[i][j] != -1):
        return False
 
    return True
 
# Function to replace all of the O's in the matrix
# with their shortest distance from a guard
def findDistance(matrix):
    output = [[ -1 for i in range(N)]for i in range(M)]
    q = queue()
 
    # finding Guards location and adding into queue
    for i in range(M):
        for j in range(N):
             
            # initialize each cell as -1
            output[i][j] = -1
            if (matrix[i][j] == 'G'):
                pos = [i, j, 0]
                q.appendleft(pos)
                 
                # guard has 0 distance
                output[i][j] = 0
 
 
 
    # do till queue is empty
    while (len(q) > 0):
         
        # get the front cell in the queue and update
        # its adjacent cells
        curr = q.pop()
        x, y, dist = curr[0], curr[1], curr[2]
 
        # do for each adjacent cell
        for i in range(4):
             
            # if adjacent cell is valid, has path and
            # not visited yet, en-queue it.
 
            if isValid(x + row[i], y + col[i]) and isSafe(x + row[i], y + col[i], matrix, output) :
                output[x + row[i]][y + col[i]] = dist + 1
 
                pos = [x + row[i], y + col[i], dist + 1]
                q.appendleft(pos)
 
    # print output matrix
 
    for i in range(M):
        for j in range(N):
            if output[i][j] > 0:
                print(output[i][j], end=" ")
            else:
                print(output[i][j],end=" ")
        print()
 
 
# Driver code
 
matrix = [['O', 'O', 'O', 'O', 'G'],
    ['O', 'W', 'W', 'O', 'O'],
    ['O', 'O', 'O', 'W', 'O'],
    ['G', 'W', 'W', 'W', 'O'],
    ['O', 'O', 'O', 'O', 'G']]
 
findDistance(matrix)
 
# This code is contributed by mohit kumar 29


C#
// C# program to replace all of the O's
// in the matrix with their shortest
// distance from a guard
using System;
using System.Collections.Generic;
public class Node
{
  public int i, j, dist;
  public Node(int i, int j, int dist)
  {
    this.i = i;
    this.j = j;
    this.dist = dist;
  }
}
 
public class MinDistanceFromaGuardInBank
{
 
  // Store dimensions of the matrix
  static int M = 5;
  static int N = 5;
 
  // These arrays are used to get row
  // and column numbers of 4 neighbors
  // of a given cell
  static int[] row = { -1, 0, 1, 0 };
  static int[] col = { 0, 1, 0, -1 };
 
  // Return true if row number and
  // column number is in range
 
  static bool isValid(int i, int j)
  {
    if ((i < 0 || i > M - 1) || (j < 0 || j > N - 1))
      return false;
 
    return true;
  }
 
  // Return true if current cell is
  // an open area and its distance
  // from guard is not calculated yet
 
  static bool isSafe(int i, int j, char[,] matrix,int[,] output)
  {
    if (matrix[i,j] != 'O' || output[i,j] != -1)
    {
      return false;
    }
    return true;
  }
 
  // Function to replace all of the O's
  // in the matrix with their shortest
  // distance from a guard
  static void findDistance(char[,] matrix)
  {
    int[,] output = new int[M,N];
    Queue q = new Queue();
 
    // Finding Guards location and
    // adding into queue
    for(int i = 0; i < M; i++)
    {
      for(int j = 0; j < N; j++)
      {
 
        // Initialize each cell as -1
        output[i, j] = -1;
 
        if (matrix[i, j] == 'G')
        {
          q.Enqueue(new Node(i, j, 0));
 
          // Guard has 0 distance
          output[i, j] = 0;
        }
      }
    }
 
    // Do till queue is empty
    while (q.Count != 0)
    {
      // Get the front cell in the queue
      // and update its adjacent cells
      Node curr = q.Peek();  
 
      int x = curr.i;
      int y = curr.j;
      int dist = curr.dist;
 
      // Do for each adjacent cell
      for (int i = 0; i < 4; i++)
      {
 
        // If adjacent cell is valid, has
        // path and not visited yet,
        // en-queue it.     
        if (isValid(x + row[i], y + col[i]))
        {
          if (isSafe(x + row[i], y + col[i],matrix, output))
          {
            output[x + row[i] , y + col[i]] = dist + 1;
            q.Enqueue(new Node(x + row[i],y + col[i],dist + 1));
          }
        }
      }
 
      // Dequeue the front cell as
      // its distance is found
      q.Dequeue();
 
    }
 
    // Print output matrix
    for(int i = 0; i < M; i++)
    {
      for(int j = 0; j < N; j++)
      {
        Console.Write(output[i,j] + " ");
      }
      Console.WriteLine();
    }
  }
 
  // Driver code
  static public void Main ()
  {
    char[,] matrix ={ { 'O', 'O', 'O', 'O', 'G' },
                     { 'O', 'W', 'W', 'O', 'O' },
                     { 'O', 'O', 'O', 'W', 'O' },
                     { 'G', 'W', 'W', 'W', 'O' },
                     { 'O', 'O', 'O', 'O', 'G' } };
 
    findDistance(matrix);
  }
}
 
// This code is contributed by avanitrachhadiya2155


Javascript


输出:

3  3  2  1  0
  2 -1 -1  2  1
  1  2  3 -1  2
  0 -1 -1 -1  1
  1  2  2  1  0