Open In App

Minimum hours taken by Zombies to infect all Humans by infecting up, left, down and right only

Last Updated : 13 Jul, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given a 2D grid, each cell is either a zombie 1 or human 0. Zombies can turn adjacent horizont or vertical (up/down/left/right) human beings into zombies every hour. The task is to find out how many hours it will take to infect all humans. 

Examples: 

Input: arr[][] = { { 0, 1, 0, 1 }, 
                          { 0, 0, 0, 0 }, 
                         { 0, 0, 0, 1 } };
Output:  3
Explanation: In time = 3 hours all the humans will be converted to zombie.

Input:  arr[][] = {{ 0, 1, 0 }, 
                          { 0, 0, 0 }, 
                         { 0, 0, 0 }};
Output: 3

 

Approach: This problem can be solved by using Multi-source BFS. Follow the steps below to solve the given problem. 

  • Because all the zombies are expanding at the same time so multi-source BFS need to be used.
  • Initially push all the zombies positions into the queue.
  • While queue is not empty try to visit all the four directions for each zombies because effect of each zombie will be in all the four directions.
  • After each set of zombies increment the time by 1.
  • At Check if any cell is left to be human that means initially no zombie was there in the grid so return -1.
  • Otherwise return the total time taken to infect all the humans.

Below is the implementation of the above approach: 

C++14




// C++ program for above approach
#include <bits/stdc++.h>
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<vector<int> >& grid)
{
    // Queue to store coordinates for BFS
    queue<pair<int, int> > 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<vector<int> > 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<pair> q = new LinkedList<GFG.pair>();
 
        // 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


C#




// C# program for above approach
 
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // To check if current coordinate lies inside the grid
    // or not
    static bool isValid(int i, int j, int n, int m)
    {
        if (i < n && i >= 0 && j < m && j >= 0) {
            return true;
        }
        return false;
    }
 
    class pair {
        public 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<pair> q = new Queue<pair>();
 
        // Number of rows
        int n = grid.GetLength(0);
 
        // Number of columns
        int m = grid.GetLength(1);
 
        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.Enqueue(new pair(i, j));
                    cur++;
                }
            }
        }
 
        // To keep track of the time
        int t = 0;
 
        // While any zombie is left
        while (q.Count != 0) {
            for (int i = 0; i < cur; i++) {
                pair use = q.Peek();
                q.Dequeue();
                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.Enqueue(new pair(x + 1, y));
                    next++;
                }
                if (isValid(x - 1, y, n, m)
                    && grid[x - 1, y] == 0) {
                    grid[x - 1, y] = 1;
                    q.Enqueue(new pair(x - 1, y));
                    next++;
                }
                if (isValid(x, y + 1, n, m)
                    && grid[x, y + 1] == 0) {
                    grid[x, y + 1] = 1;
                    q.Enqueue(new pair(x, y + 1));
                    next++;
                }
                if (isValid(x, y - 1, n, m)
                    && grid[x, y - 1] == 0) {
                    grid[x, y - 1] = 1;
                    q.Enqueue(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;
    }
 
    static public void Main()
    {
 
        // Code
        // int N = 3, M = 4;
 
        // Given grid
        int[, ] grid = new int[3, 4] { { 0, 1, 0, 1 },
                                       { 0, 0, 0, 0 },
                                       { 0, 0, 0, 1 } };
 
        // Function call
        Console.Write(zombieInfection(grid));
    }
}
 
// This code is contributed by lokesh(lokeshmvs21).


Javascript




<script>
   // JavaScript code for the above approach
 
   // To check if current coordinate
   // lies inside the grid or not
   function isValid(i, j, n, m) {
     if (i < n && i >= 0 && j < m && j >= 0)
       return 1;
     else
       return 0;
   }
 
   // Function to find out minimum time required
   // to infect all humans into zombies
   function zombieInfection(grid)
   {
    
     // Queue to store coordinates for BFS
     let q = [];
 
     // Number of rows
     let n = grid.length;
 
     // Number of columns
     let m = grid[0].length;
 
     let cur = 0, next = 0;
 
     // Initially pushing coordinates of all the
     // zombies into the queue
     for (let i = 0; i < n; i++) {
       for (let j = 0; j < m; j++) {
 
         // If cell is zombie
         if (grid[i][j] == 1) {
           q.push({ first: i, second: j });
           cur++;
         }
       }
     }
 
     // To keep track of the time
     let t = 0;
 
     // While any zombie is left
     while (q.length != 0) {
       for (let i = 0; i < cur; i++) {
         let use = q[0];
         q.shift();
         let 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.push({ first: x + 1, second: y });
           next++;
         }
         if (isValid(x - 1, y, n, m)
           && grid[x - 1][y] == 0) {
           grid[x - 1][y] = 1;
           q.push({ first: x - 1, second: y });
           next++;
         }
         if (isValid(x, y + 1, n, m)
           && grid[x][y + 1] == 0) {
           grid[x][y + 1] = 1;
           q.push({ first: x, second: y + 1 });
           next++;
         }
         if (isValid(x, y - 1, n, m)
           && grid[x][y - 1] == 0) {
           grid[x][y - 1] = 1;
           q.push({ first: x, second: 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 (let i = 0; i < n; i++)
       for (let j = 0; j < m; j++)
         if (grid[i][j] == 0)
           return -1;
 
     // Return the total time elapsed
     return t;
   }
 
   // Driver Code
 
   let N = 3, M = 4;
 
   // Given grid
   let grid = [[0, 1, 0, 1],
   [0, 0, 0, 0],
   [0, 0, 0, 1]];
 
   // Function Call
   document.write(zombieInfection(grid));
 
 // This code is contributed by Potta Lokesh
 </script>


Output

3

Time Complexity: O(N*M) 
Auxiliary Space: O(N*M)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads