📌  相关文章
📜  检查值为1的单元格是否在到达值为2的任何单元格之前到达矩阵右下角的路径

📅  最后修改于: 2021-04-29 03:59:57             🧑  作者: Mango

给定一个矩阵ARR [] []的尺寸N * M个中,具有元件0,1,2。矩阵中只有一个值为1的单元格。任务是检查是否有可能1到达任何值为2的单元格之前右下角或不使用以下操作:

  • 2可以在1个单位时间内在所有四个方向上复制1个单位。
  • 如果该位置的元素为0 ,则1只能在所有四个方向中的一个方向上移动。

如果值1的单元格比任何值2的单元格在少于或等于的时间内到达右下角,请打印“是” 。否则,打印“ 1”

例子:

方法:想法是使用多源BFS。要执行多源BFS遍历,请以Deque按指定顺序将矩阵中存在的12 s的所有位置相加。通过弹出添加的位置并添加尚未访问的相邻位置,对该出队执行BFS。请按照以下步骤解决问题:

  1. 为多源BFS创建出队。
  2. 首先,将位置为1的位置添加到前面,然后将位置为2的位置添加到后面。这是因为如果12同时到达右下角,则将1视为2之上。
  3. 从出队队列的前面弹出元素,直到出队队列为空,然后执行以下操作:
    • 如果弹出位置已被访问,则继续下一个位置。
    • 如果未访问该位置,请检查该位置是否在右下角,以及检查其中的元素是否为1 。如果发现是真的,则打印“是”
    • 否则,对于所有四个方向,将当前位置插入出队
  4. 完成上述操作后,如果未发现值1的单元格到达右下位置,则打印No。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
// Function to check if cell with
// value 1 doesn't reaches the bottom
// right cell or not
bool reachesBottom(vector >& a)
{
    // Number of rows and columns
    int n = a.size();
    int m = a[0].size();
 
    // Initialise the deque
    deque > q;
 
    // Traverse the matrix
    for (int i = 0; i < n; i++) {
 
        for (int j = 0; j < m; j++) {
 
            // Push 1 to front of queue
            if (a[i][j] == 1) {
                q.push_front({ i, j, 1 });
            }
 
            // Push 2 to back of queue
            else if (a[i][j] == 2) {
                q.push_back({ i, j, 2 });
            }
 
            a[i][j] = 0;
        }
    }
 
    // Store all the possible direction
    // of the current cell
    int dx[] = { -1, 0, 1, 0 };
    int dy[] = { 0, 1, 0, -1 };
 
    // Run multi-source BFS
    while (!q.empty()) {
 
        // Get the front element
        auto front = q.front();
 
        // Pop the front element
        q.pop_front();
 
        int i = front[0], j = front[1];
        int t = front[2];
 
        if (a[i][j])
            continue;
 
        a[i][j] = 1;
 
        // If 1 reached corner first
        if (t == 1 and (i == n - 1
                        && j == m - 1)) {
            return true;
        }
 
        for (int d = 0; d < 4; d++) {
            int ni = i + dx[d];
            int nj = j + dy[d];
 
            // Insert new point in queue
            if (ni >= 0 and ni < n
                and nj >= 0 and nj < m) {
                q.push_back({ ni, nj, t });
            }
        }
    }
 
    // If 1 can't reach the botton
    // right then return false
    return false;
}
 
// Driver Code
int main()
{
    // Given matrix
    vector > matrix{ { 0, 2, 0 },
                                 { 0, 1, 0 },
                                 { 0, 2, 0 } };
 
    // Function Call
    if (reachesBottom(matrix)) {
        cout << "YES";
    }
    else {
        cout << "NO";
    }
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
import java.lang.*;
 
class GFG{
 
// Function to check if cell with
// value 1 doesn't reaches the bottom
// right cell or not
static boolean reachesBottom(int[][] a)
{
     
    // Number of rows and columns
    int n = a.length;
    int m = a[0].length;
 
    // Initialise the deque
    Deque q = new LinkedList<>();
 
    // Traverse the matrix
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
 
            // Push 1 to front of queue
            if (a[i][j] == 1)
            {
                q.addFirst(new int[]{ i, j, 1 });
            }
 
            // Push 2 to back of queue
            else if (a[i][j] == 2)
            {
                q.addLast(new int[]{ i, j, 2 });
            }
            a[i][j] = 0;
        }
    }
 
    // Store all the possible direction
    // of the current cell
    int dx[] = { -1, 0, 1, 0 };
    int dy[] = { 0, 1, 0, -1 };
 
    // Run multi-source BFS
    while (!q.isEmpty())
    {
         
        // Get the front element
        int[] front = q.peekFirst();
 
        // Pop the front element
        q.removeFirst();
 
        int i = front[0], j = front[1];
        int t = front[2];
 
        if (a[i][j] == 1)
            continue;
 
        a[i][j] = 1;
 
        // If 1 reached corner first
        if (t == 1 && (i == n - 1 &&
                       j == m - 1))
        {
            return true;
        }
 
        for(int d = 0; d < 4; d++)
        {
            int ni = i + dx[d];
            int nj = j + dy[d];
 
            // Insert new point in queue
            if (ni >= 0 && ni < n &&
                nj >= 0 && nj < m)
            {
                q.addLast(new int[]{ ni, nj, t });
            }
        }
    }
 
    // If 1 can't reach the botton
    // right then return false
    return false;
}
 
// Driver Code
public static void main (String[] args)
{
 
    // Given matrix
    int[][] matrix = { { 0, 2, 0 },
                       { 0, 1, 0 },
                       { 0, 2, 0 } };
                        
    // Function call
    if (reachesBottom(matrix))
    {
        System.out.print("YES");
    }
    else
    {
        System.out.print("NO");
    }
}
}
 
// This code is contributed by offbeat


Python3
# Python3 program for the above approach
from collections import deque
 
# Function to check if cell with
# value 1 doesn't reaches the bottom
# right cell or not
def reachesBottom(a):
     
    # Number of rows and columns
    n = len(a)
    m = len(a[0])
 
    # Initialise the deque
    q = deque()
 
    # Traverse the matrix
    for i in range(n):
        for j in range(m):
 
            # Push 1 to front of queue
            if (a[i][j] == 1):
                q.appendleft([i, j, 1])
 
            # Push 2 to back of queue
            elif (a[i][j] == 2):
                q.append([i, j, 2])
 
            a[i][j] = 0
 
    # Store all the possible direction
    # of the current cell
    dx = [ -1, 0, 1, 0 ]
    dy = [ 0, 1, 0, -1 ]
 
    # Run multi-source BFS
    while (len(q) > 0):
 
        # Get the front element
        front = q.popleft()
        i = front[0]
        j = front[1]
        t = front[2]
 
        if (a[i][j]):
            continue
 
        a[i][j] = 1
 
        # If 1 reached corner first
        if (t == 1 and (i == n - 1 and
                        j == m - 1)):
            return True
 
        for d in range(4):
            ni = i + dx[d]
            nj = j + dy[d]
 
            # Insert new poin queue
            if (ni >= 0 and ni < n and
                nj >= 0 and nj < m):
                q.append([ni, nj, t])
 
    # If 1 can't reach the botton
    # right then return false
    return False
 
# Driver Code
if __name__ == '__main__':
     
    # Given matrix
    matrix = [ [ 0, 2, 0 ],
               [ 0, 1, 0 ],
               [ 0, 2, 0 ] ]
 
    # Function call
    if (reachesBottom(matrix)):
        print("YES")
    else:
        print("NO")
 
# This code is contributed by mohit kumar 29


C#
// C# program for
// the above approach
using System;
using System.Collections.Generic;
class GFG{
 
// Function to check if cell with
// value 1 doesn't reaches the bottom
// right cell or not
static bool reachesBottom(int [,]a,
                          int n, int m)
{
  // Initialise the deque
  Queue q = new Queue();
 
  // Traverse the matrix
  for(int i = 0; i < n; i++)
  {
    for(int j = 0; j < m; j++)
    {
      // Push 1 to front of queue
      if (a[i, j] == 1)
      {
        q.Enqueue(new int[]{i, j, 1});
      }
 
      // Push 2 to back of queue
      else if (a[i, j] == 2)
      {
        q.Enqueue(new int[]{i, j, 2});
      }
      a[i, j] = 0;
    }
  }
 
  // Store all the possible direction
  // of the current cell
  int []dx = {-1, 0, 1, 0};
  int []dy = {0, 1, 0, -1};
 
  // Run multi-source BFS
  while (q.Count != 0)
  {
    // Get the front element
    int[] front = q.Peek();
 
    // Pop the front element
    q.Dequeue();
 
    int i = front[0], j = front[1];
    int t = front[2];
 
    if (a[i, j] == 1)
      continue;
 
    a[i, j] = 1;
 
    // If 1 reached corner first
    if (t == 1 && (i == n - 1 &&
                   j == m - 1))
    {
      return true;
    }
 
    for(int d = 0; d < 4; d++)
    {
      int ni = i + dx[d];
      int nj = j + dy[d];
 
      // Insert new point in queue
      if (ni >= 0 && ni < n &&
          nj >= 0 && nj < m)
      {
        q.Enqueue(new int[]{ni, nj, t});
      }
    }
  }
 
  // If 1 can't reach the botton
  // right then return false
  return false;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given matrix
  int[,] matrix = {{0, 2, 0},
                   {0, 1, 0},
                   {0, 2, 0}};
 
  // Function call
  if (reachesBottom(matrix, 3, 3))
  {
    Console.Write("YES");
  }
  else
  {
    Console.Write("NO");
  }
}
}
 
// This code is contributed by gauravrajput1


输出:
NO


时间复杂度: O(N * M)
辅助空间: O(N * M)