📜  网格中一次覆盖所有非障碍块的唯一路径

📅  最后修改于: 2021-04-29 04:48:20             🧑  作者: Mango

给定具有4种类型的块的grid [] []

  • 1代表起始块。恰好有一个起点。
  • 2表示结束块。恰好有一个结尾块。
  • 0代表我们可以走过去的空白块。
  • -1表示我们无法越过的障碍。

任务是计算从起始块到结束块的路径数,以使每个无障碍块都被准确覆盖一次。

例子:

方法:我们可以在这里使用简单的DFS进行回溯。我们可以通过计算途中遇到的所有障碍物,并最终将其与可用的障碍物总数进行比较(如果它们匹配),来检查特定路径是否覆盖了所有非障碍障碍物,然后将其添加为有效解决方案。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
 
// Function for dfs.
// i, j ==> Current cell indexes
// vis ==> To mark visited cells
// ans ==> Result
// z ==> Current count 0s visited
// z_count ==> Total 0s present
void dfs(int i, int j, vector >& grid,
         vector >& vis, int& ans,
         int z, int z_count)
{
    int n = grid.size(), m = grid[0].size();
 
    // Mark the block as visited
    vis[i][j] = 1;
    if (grid[i][j] == 0)
 
        // update the count
        z++;
 
    // If end block reached
    if (grid[i][j] == 2) {
 
        // If path covered all the non-
        // obstacle blocks
        if (z == z_count)
            ans++;
        vis[i][j] = 0;
        return;
    }
 
    // Up
    if (i >= 1 && !vis[i - 1][j] && grid[i - 1][j] != -1)
        dfs(i - 1, j, grid, vis, ans, z, z_count);
 
    // Down
    if (i < n - 1 && !vis[i + 1][j] && grid[i + 1][j] != -1)
        dfs(i + 1, j, grid, vis, ans, z, z_count);
 
    // Left
    if (j >= 1 && !vis[i][j - 1] && grid[i][j - 1] != -1)
        dfs(i, j - 1, grid, vis, ans, z, z_count);
 
    // Right
    if (j < m - 1 && !vis[i][j + 1] && grid[i][j + 1] != -1)
        dfs(i, j + 1, grid, vis, ans, z, z_count);
 
    // Unmark the block (unvisited)
    vis[i][j] = 0;
}
 
// Function to return the count of the unique paths
int uniquePaths(vector >& grid)
{
    int z_count = 0; // Total 0s present
    int n = grid.size(), m = grid[0].size();
    int ans = 0;
    vector > vis(n, vector(m, 0));
    int x, y;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
 
            // Count non-obstacle blocks
            if (grid[i][j] == 0)
                z_count++;
            else if (grid[i][j] == 1) {
 
                // Starting position
                x = i, y = j;
            }
        }
    }
    dfs(x, y, grid, vis, ans, 0, z_count);
    return ans;
}
 
// Driver code
int main()
{
    vector > grid{ { 1, 0, 0, 0 },
                               { 0, 0, 0, 0 },
                               { 0, 0, 2, -1 } };
 
    cout << uniquePaths(grid);
    return 0;
}


Java
// Java implementation of the approach
import java.util.Arrays;
class GFG
{
  static int ans = 0;
 
  // Function for dfs.
  // i, j ==> Current cell indexes
  // vis ==> To mark visited cells
  // ans ==> Result
  // z ==> Current count 0s visited
  // z_count ==> Total 0s present
  static void dfs(int i, int j, int[][] grid,
                  boolean[][] vis, int z, int z_count)
  {
    int n = grid.length, m = grid[0].length;
 
    // Mark the block as visited
    vis[i][j] = true;
    if (grid[i][j] == 0)
 
      // update the count
      z++;
 
    // If end block reached
    if (grid[i][j] == 2)
    {
 
      // If path covered all the non-
      // obstacle blocks
      if (z == z_count)
        ans++;
      vis[i][j] = false;
      return;
    }
 
    // Up
    if (i >= 1 && !vis[i - 1][j] && grid[i - 1][j] != -1)
      dfs(i - 1, j, grid, vis, z, z_count);
 
    // Down
    if (i < n - 1 && !vis[i + 1][j] && grid[i + 1][j] != -1)
      dfs(i + 1, j, grid, vis, z, z_count);
 
    // Left
    if (j >= 1 && !vis[i][j - 1] && grid[i][j - 1] != -1)
      dfs(i, j - 1, grid, vis, z, z_count);
 
    // Right
    if (j < m - 1 && !vis[i][j + 1] && grid[i][j + 1] != -1)
      dfs(i, j + 1, grid, vis, z, z_count);
 
    // Unmark the block (unvisited)
    vis[i][j] = false;
  }
 
  // Function to return the count of the unique paths
  static int uniquePaths(int[][] grid)
  {
    int z_count = 0; // Total 0s present
    int n = grid.length, m = grid[0].length;
 
    boolean[][] vis = new boolean[n][m];
    for (int i = 0; i < n; i++)
    {
      Arrays.fill(vis[i], false);
    }
    int x = 0, y = 0;
    for (int i = 0; i < n; ++i)
    {
      for (int j = 0; j < m; ++j)
      {
 
        // Count non-obstacle blocks
        if (grid[i][j] == 0)
          z_count++;
        else if (grid[i][j] == 1)
        {
 
          // Starting position
          x = i;
          y = j;
        }
      }
    }
    dfs(x, y, grid, vis, 0, z_count);
    return ans;
  }
 
  // Driver code
  public static void main(String[] args)
  {
 
    int[][] grid = { { 1, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 2, -1 } };
    System.out.println(uniquePaths(grid));
  }
}
 
// This code is contributed by sanjeev2552


Python3
# Python3 implementation of the approach
 
# Function for dfs.
# i, j ==> Current cell indexes
# vis ==> To mark visited cells
# ans ==> Result
# z ==> Current count 0s visited
# z_count ==> Total 0s present
def dfs(i, j, grid, vis, ans, z, z_count):
 
    n = len(grid)
    m = len(grid[0])
 
    # Mark the block as visited
    vis[i][j] = 1
     
    if (grid[i][j] == 0):
 
        # Update the count
        z += 1
 
    # If end block reached
    if (grid[i][j] == 2):
 
        # If path covered all the non-
        # obstacle blocks
        if (z == z_count):
            ans += 1
             
        vis[i][j] = 0
         
        return grid, vis, ans
         
    # Up
    if (i >= 1 and not vis[i - 1][j] and
                      grid[i - 1][j] != -1):
        grid, vis, ans = dfs(i - 1, j, grid,
                             vis, ans, z,
                             z_count)
 
    # Down
    if (i < n - 1 and not vis[i + 1][j] and
                         grid[i + 1][j] != -1):
        grid, vis, ans = dfs(i + 1, j, grid,
                             vis, ans, z,
                             z_count)
 
    # Left
    if (j >= 1 and not vis[i][j - 1] and
                      grid[i][j - 1] != -1):
        grid, vis, ans = dfs(i, j - 1, grid,
                             vis, ans, z,
                             z_count)
 
    # Right
    if (j < m - 1 and not vis[i][j + 1] and
                         grid[i][j + 1] != -1):
        grid, vis, ans = dfs(i, j + 1, grid,
                             vis, ans, z,
                             z_count)
 
    # Unmark the block (unvisited)
    vis[i][j] = 0
     
    return grid, vis, ans
 
# Function to return the count
# of the unique paths
def uniquePaths(grid):
     
    # Total 0s present
    z_count = 0
    n = len(grid)
    m = len(grid[0])
    ans = 0
     
    vis = [[0 for j in range(m)]
              for i in range(n)]
     
    x = 0
    y = 0
     
    for i in range(n):
        for j in range(m):
             
            # Count non-obstacle blocks
            if grid[i][j] == 0:
                z_count += 1
                 
            elif (grid[i][j] == 1):
                 
                # Starting position
                x = i
                y = j
         
    grid, vis, ans = dfs(x, y, grid,
                         vis, ans, 0,
                         z_count)
                          
    return ans
 
# Driver code
if __name__=='__main__':
 
    grid = [ [ 1, 0, 0, 0 ],
             [ 0, 0, 0, 0 ],
             [ 0, 0, 2, -1 ] ]
              
    print(uniquePaths(grid))
     
# This code is contributed by rutvik_56


输出:
2