📌  相关文章
📜  僵尸通过仅向上、向左、向下和向右感染来感染所有人类所需的最少时间

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

僵尸通过仅向上、向左、向下和向右感染来感染所有人类所需的最少时间

给定一个2D网格,每个单元格要么是僵尸1要么是人类0 。僵尸每小时可以将相邻的水平或垂直(上/下/左/右)人类变成僵尸。任务是找出感染所有人类需要多少小时。

例子:

方法:这个问题可以通过使用多源BFS来解决。请按照以下步骤解决给定的问题。

  • 因为所有的僵尸都在同时扩展,所以需要使用多源 BFS
  • 最初将所有僵尸位置推入队列
  • 虽然队列不为空,但尝试访问每个僵尸的所有四个方向,因为每个僵尸的效果将在所有四个方向上。
  • 在每组僵尸之后将时间增加1
  • 在检查是否有任何单元格留给人类,这意味着最初网格中没有僵尸,所以返回 -1
  • 否则返回感染所有人类所需的总时间

下面是上述方法的实现:

C++14
// C++ program for above approach
#include 
using namespace std;
 
// To check if current coordinate
// lies inside the grid or not
bool isValid(int i, int j, int n, int m)
{
    if (i < n and i >= 0 and j < m and j >= 0)
        return 1;
    else
        return 0;
}
 
// Function to find out minimum time required
// to infect all humans into zombies
int zombieInfection(vector >& grid)
{
    // Queue to store coordinates for BFS
    queue > q;
 
    // Number of rows
    int n = grid.size();
 
    // Number of columns
    int m = grid[0].size();
 
    int cur = 0, next = 0;
 
    // Initially pushing coordinates of all the
    // zombies into the queue
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
 
            // If cell is zombie
            if (grid[i][j] == 1) {
                q.push({ i, j });
                cur++;
            }
        }
    }
 
    // To keep track of the time
    int t = 0;
 
    // While any zombie is left
    while (!q.empty()) {
        for (int i = 0; i < cur; i++) {
            auto use = q.front();
            q.pop();
            int x = use.first, y = use.second;
 
            // Checking for all the four directons
            // horizontally and vertically
            if (isValid(x + 1, y, n, m)
                and grid[x + 1][y] == 0) {
                grid[x + 1][y] = 1;
                q.push({ x + 1, y });
                next++;
            }
            if (isValid(x - 1, y, n, m)
                and grid[x - 1][y] == 0) {
                grid[x - 1][y] = 1;
                q.push({ x - 1, y });
                next++;
            }
            if (isValid(x, y + 1, n, m)
                and grid[x][y + 1] == 0) {
                grid[x][y + 1] = 1;
                q.push({ x, y + 1 });
                next++;
            }
            if (isValid(x, y - 1, n, m)
                and grid[x][y - 1] == 0) {
                grid[x][y - 1] = 1;
                q.push({ x, y - 1 });
                next++;
            }
        }
        if (next == 0)
            break;
        cur = next;
        next = 0;
 
        // Increment time
        t++;
    }
 
    // If no zombie was there in the grid
    // Then it is not possible to convert all
    // the humans to zombie so return -1
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (grid[i][j] == 0)
                return -1;
 
    // Return the total time elapsed
    return t;
}
 
// Driver Code
int main()
{
    int N = 3, M = 4;
 
    // Given grid
    vector > grid = { { 0, 1, 0, 1 },
                                  { 0, 0, 0, 0 },
                                  { 0, 0, 0, 1 } };
 
    // Function Call
    cout << zombieInfection(grid);
 
    return 0;
}


Java
// Java program for above approach
import java.util.*;
class GFG
{
 
  // To check if current coordinate
  // lies inside the grid or not
  static boolean isValid(int i, int j, int n, int m)
  {
    if (i < n && i >= 0 && j < m && j >= 0)
      return true;
    else
      return false;
  }
  static class pair
  {
    int first, second;
    public pair(int first, int second) 
    {
      this.first = first;
      this.second = second;
    }   
  }
 
  // Function to find out minimum time required
  // to infect all humans into zombies
  static int zombieInfection(int [][]grid)
  {
 
    // Queue to store coordinates for BFS
    Queue q = new LinkedList();
 
    // Number of rows
    int n = grid.length;
 
    // Number of columns
    int m = grid[0].length;
 
    int cur = 0, next = 0;
 
    // Initially pushing coordinates of all the
    // zombies into the queue
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
 
        // If cell is zombie
        if (grid[i][j] == 1) {
          q.add(new pair( i, j ));
          cur++;
        }
      }
    }
 
    // To keep track of the time
    int t = 0;
 
    // While any zombie is left
    while (!q.isEmpty()) {
      for (int i = 0; i < cur; i++) {
        pair use = q.peek();
        q.remove();
        int x = use.first, y = use.second;
 
        // Checking for all the four directons
        // horizontally and vertically
        if (isValid(x + 1, y, n, m)
            && grid[x + 1][y] == 0) {
          grid[x + 1][y] = 1;
          q.add(new pair(  x + 1, y ));
          next++;
        }
        if (isValid(x - 1, y, n, m)
            && grid[x - 1][y] == 0) {
          grid[x - 1][y] = 1;
          q.add(new pair(  x - 1, y ));
          next++;
        }
        if (isValid(x, y + 1, n, m)
            && grid[x][y + 1] == 0) {
          grid[x][y + 1] = 1;
          q.add(new pair(  x, y + 1 ));
          next++;
        }
        if (isValid(x, y - 1, n, m)
            && grid[x][y - 1] == 0) {
          grid[x][y - 1] = 1;
          q.add(new pair(  x, y - 1 ));
          next++;
        }
      }
      if (next == 0)
        break;
      cur = next;
      next = 0;
 
      // Increment time
      t++;
    }
 
    // If no zombie was there in the grid
    // Then it is not possible to convert all
    // the humans to zombie so return -1
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++)
        if (grid[i][j] == 0)
          return -1;
 
    // Return the total time elapsed
    return t;
  }
 
  // Driver Code
  public static void main(String[] args)
  {
    int N = 3, M = 4;
 
    // Given grid
    int [][]grid = { { 0, 1, 0, 1 },
                    { 0, 0, 0, 0 },
                    { 0, 0, 0, 1 } };
 
    // Function Call
    System.out.print(zombieInfection(grid));
 
  }
}
 
// This code is contributed by 29AjayKumar


Python3
# python program for above approach
from queue import Queue
 
# To check if current coordinate
# lies inside the grid or not
def isValid(i, j, n, m):
 
    if (i < n and i >= 0 and j < m and j >= 0):
        return 1
    else:
        return 0
 
# Function to find out minimum time required
# to infect all humans into zombies
def zombieInfection(grid):
 
    # Queue to store coordinates for BFS
    q = Queue()
 
    # Number of rows
    n = len(grid)
 
    # Number of columns
    m = len(grid[0])
 
    cur = 0
    next = 0
 
    # Initially pushing coordinates of all the
    # zombies into the queue
 
    for i in range(0, n):
        for j in range(0, m):
 
                        # If cell is zombie
            if (grid[i][j] == 1):
                q.put([i, j])
                cur += 1
 
        # To keep track of the time
    t = 0
 
    # While any zombie is left
    while (not q.empty()):
        for i in range(0, cur):
            use = q.get()
            x = use[0]
            y = use[1]
 
            # Checking for all the four directons
            # horizontally and vertically
            if (isValid(x + 1, y, n, m)
                    and grid[x + 1][y] == 0):
                grid[x + 1][y] = 1
                q.put([x + 1, y])
                next += 1
 
            if (isValid(x - 1, y, n, m)
                    and grid[x - 1][y] == 0):
                grid[x - 1][y] = 1
                q.put([x - 1, y])
                next += 1
 
            if (isValid(x, y + 1, n, m)
                    and grid[x][y + 1] == 0):
                grid[x][y + 1] = 1
                q.put([x, y + 1])
                next += 1
 
            if (isValid(x, y - 1, n, m)
                    and grid[x][y - 1] == 0):
                grid[x][y - 1] = 1
                q.put([x, y - 1])
                next += 1
 
        if (next == 0):
            break
 
        cur = next
        next = 0
 
        # Increment time
        t += 1
 
        # If no zombie was there in the grid
        # Then it is not possible to convert all
        # the humans to zombie so return -1
    for i in range(0, n):
        for j in range(0, m):
            if (grid[i][j] == 0):
                return -1
 
        # Return the total time elapsed
    return t
 
# Driver Code
if __name__ == "__main__":
 
    N = 3
    M = 4
 
    # Given grid
    grid = [[0, 1, 0, 1],
            [0, 0, 0, 0],
            [0, 0, 0, 1]]
 
    # Function Call
    print(zombieInfection(grid))
 
    # This code is contributed by rakeshsahni


Javascript


输出
3

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