📜  所有患者感染所需的最长时间

📅  最后修改于: 2021-09-04 07:47:54             🧑  作者: Mango

给定一个矩阵arr[][] ,仅由 0、1 和 2 组成,分别表示空病房未感染患者感染患者。在一个时间单位,被感染的人在索引(i,j)的可感染邻近它即未感染的人,在索引(i – 1,j)中,第(i + 1,j)的(I,J – 1 )(i, j + 1) 。任务是找到感染所有患者所需的最短时间。如果不可能感染所有患者,则打印“-1”

例子:

方法:给定的问题可以通过在二维矩阵上使用 BFS 遍历来解决。请按照以下步骤解决给定的问题:

  • -1初始化一个二维数组,比如timeofinfection[][] ,这样timeofinfection[i][j]存储索引(i, j)处的患者被感染的时间。
  • 初始化队列以存储受感染患者的索引及其感染时间。
  • 遍历给定矩阵arr[][]并执行以下操作:
    • 如果单元格(i, j) 处的值为2 ,则将该单元格推入队列,感染时间为0,{i, j, 0}
    • 迭代直到队列非空并执行以下步骤:
      • 弹出队列的前端元素并将其存储在一个变量中,比如current
      • 从当前弹出的单元格(i, j) 开始,如果相邻单元格有未访问的感染者,则将具有(1 + 当前弹出单元格的感染时间)的相邻单元格的索引推入队列。
  • 完成上述步骤后,如果访问了所有感染者,即所有感染者的感染时间为非负,则打印矩阵timeofinfection[][]中存在的最大元素作为所需的最大时间单位感染所有患者。
  • 否则,打印“-1”

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Direction arrays
vector > direction
    = { { 1, 0 }, { 0, -1 }, { -1, 0 }, { 0, 1 } };
 
// Function to find the maximum time
// required for all patients to get infected
int maximumTime(vector > arr)
{
    // Stores the number of rows
    int n = arr.size();
 
    // Stores the number of columns
    int m = arr[0].size();
 
    // Stores the time of infection
    // of the patient at index (i, j)
    int timeofinfection[n][m];
 
    // Stores index and time of
    // infection of infected persions
    queue, int> > q;
 
    // Traverse the matrix
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
 
            // Set the cell as unvisited
            timeofinfection[i][j] = -1;
 
            // If the current patient
            // is already infected
            if (arr[i][j] == 2) {
 
                // Push the index and time of
                // infection of current patient
                q.push({ { i, j }, 0 });
                timeofinfection[i][j] = 0;
            }
        }
    }
 
    // Iterate until queue becomes empty
    while (!q.empty()) {
        // Stores the front element of queue
        pair, int> current
            = q.front();
 
        // Pop out the front element
        q.pop();
 
        // Check for all four
        // adjacent indices
        for (auto it : direction) {
 
            // Find the index of the
            // adjacent cell
            int i = current.first.first
                    + it.first;
            int j = current.first.second
                    + it.second;
 
            // If the current adjacent
            // cell is invalid or it
            // contains an infected patient
            if (i < 0 || j < 0 || i >= n
                || j >= m || arr[i][j] != 1
                || timeofinfection[i][j] != -1) {
 
                // Continue to the next
                // neighbouring cell
                continue;
            }
 
            // Push the infected
            // neighbour into queue
            q.push({ { i, j },
                     current.second + 1 });
            timeofinfection[i][j]
                = current.second + 1;
        }
    }
 
    // Stores the maximum time
    int maxi = INT_MIN;
 
    // Stores if any uninfected
    // patient exists or not
    int flag = 0;
 
    // Traverse the matrix
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            // If no patient is
            // present at index (i, j)
            if (arr[i][j] != 1)
                continue;
 
            // If an uninfected patient
            // is present at index (i, j)
            if (arr[i][j] == 1
                && timeofinfection[i][j] == -1) {
                // Set flag as true
                flag = 1;
                break;
            }
 
            // Update the maximum time of infection
            maxi = max(maxi, timeofinfection[i][j]);
        }
    }
 
    // If an ininfected patient is present
    if (flag)
        return -1;
 
    // Return the final result
    return maxi;
}
 
// Driver Code
int main()
{
    vector > arr
        = { { 2, 1, 0, 2, 1 },
            { 1, 0, 1, 2, 1 },
            { 1, 0, 0, 2, 1 } };
    cout << maximumTime(arr);
 
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG {
     
static class pair
{
    int first, second, third;
     
    pair(int first,int second,int third)
    {
         this.first = first;
         this.second = second;
         this.third = third;
    }
}   
     
// Direction arrays
static int[][] direction = { { 1, 0 }, { 0, -1 },
                             { -1, 0 }, { 0, 1 } };
 
// Function to find the maximum time
// required for all patients to get infected
static int maximumTime(int[][] arr)
{
     
    // Stores the number of rows
    int n = arr.length;
 
    // Stores the number of columns
    int m = arr[0].length;
 
    // Stores the time of infection
    // of the patient at index (i, j)
    int[][] timeofinfection = new int[n][m];
 
    // Stores index and time of
    // infection of infected persions
    Queue q = new LinkedList<>();
 
    // Traverse the matrix
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
 
            // Set the cell as unvisited
            timeofinfection[i][j] = -1;
 
            // If the current patient
            // is already infected
            if (arr[i][j] == 2)
            {
                 
                // Push the index and time of
                // infection of current patient
                q.add(new pair(i, j, 0));
                timeofinfection[i][j] = 0;
            }
        }
    }
 
    // Iterate until queue becomes empty
    while (!q.isEmpty())
    {
         
        // Stores the front element of queue
        pair current = q.peek();
 
        // Pop out the front element
        q.poll();
 
        // Check for all four
        // adjacent indices
        for(int[] it : direction)
        {
             
            // Find the index of the
            // adjacent cell
            int i = current.first + it[0];
            int j = current.second + it[1];
 
            // If the current adjacent
            // cell is invalid or it
            // contains an infected patient
            if (i < 0 || j < 0 || i >= n ||
               j >= m || arr[i][j] != 1 ||
               timeofinfection[i][j] != -1)
            {
 
                // Continue to the next
                // neighbouring cell
                continue;
            }
 
            // Push the infected
            // neighbour into queue
            q.add(new pair(i, j ,
                           current.second + 1 ));
            timeofinfection[i][j] = current.third + 1;
        }
    }
 
    // Stores the maximum time
    int maxi = Integer.MIN_VALUE;
 
    // Stores if any uninfected
    // patient exists or not
    int flag = 0;
 
    // Traverse the matrix
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
             
            // If no patient is
            // present at index (i, j)
            if (arr[i][j] != 1)
                continue;
 
            // If an uninfected patient
            // is present at index (i, j)
            if (arr[i][j] == 1 && timeofinfection[i][j] == -1)
            {
                 
                // Set flag as true
                flag = 1;
                break;
            }
 
            // Update the maximum time of infection
            maxi = Math.max(maxi, timeofinfection[i][j]);
        }
    }
 
    // If an ininfected patient is present
    if (flag == 1)
        return -1;
 
    // Return the final result
    return maxi;
}
 
// Driver code
public static void main(String[] args)
{
    int[][] arr = { { 2, 1, 0, 2, 1 },
                    { 1, 0, 1, 2, 1 },
                    { 1, 0, 0, 2, 1 } };
    System.out.print(maximumTime(arr));
}
}
 
// This code is contributed by offbeat


C++
// C++ program for the above approach
#include 
using namespace std;
 
// Direction arrays
vector > direction
    = { { 1, 0 }, { 0, -1 }, { -1, 0 }, { 0, 1 } };
 
// Function to find the maximum time
// required for all patients to get infected
int maximumTime(vector > arr)
{
    // Stores the number of rows
    int n = arr.size();
 
    // Stores the number of columns
    int m = arr[0].size();
 
    // Stores wether particular index(i, j)
    // is visited or not 
    vector> visited(n,vector(m,0));
 
    // Stores index and time of
    // infection of infected persions
    queue, int> > q;
   
    //Stores uninfected patients count 
      int uninfected_count=0;
     
      //Stores time at which last person got infected
      int time = 0;
    // Traverse the matrix
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
 
            // If the current patient
            // is already infected
            if (arr[i][j] == 2) {
 
                // Push the index of current patient
                // and mark it as visited
                q.push({ { i, j }, 0 });
                visited[i][j] =  1;
            }
           
            //If current patient is uninfected
              //increment uninfected count
              if(arr[i][j] == 1){
                uninfected_count++;
            }
        }
    }
 
    // Iterate until queue becomes empty
    while (!q.empty()) {
        // Stores the front element of queue
        pair, int> current
            = q.front();
           
        time = current.second;
        // Pop out the front element
        q.pop();
 
        // Check for all four
        // adjacent indices
        for (auto it : direction) {
 
            // Find the index of the
            // adjacent cell
            int i = current.first.first
                    + it.first;
            int j = current.first.second
                    + it.second;
 
            // If the current adjacent
            // cell is invalid or it
            // contains an infected patient
            if (i < 0 || j < 0 || i >= n
                || j >= m || arr[i][j] != 1
                || visited[i][j] != 0) {
 
                // Continue to the next
                // neighbouring cell
                continue;
            }
 
            // Push the infected
            // neighbour into queue
            q.push({ { i, j }, time + 1 });
            visited[i][j] = 1;
              uninfected_count--;
        }
    }
 
    // If an uninfected patient is present
    if (uninfected_count != 0)
        return -1;
 
      // Return the final result
    return time;
}
 
// Driver Code
int main()
{
    vector > arr
        = { { 2, 1, 0, 2, 1 },
            { 1, 0, 1, 2, 1 },
            { 1, 0, 0, 2, 1 } };
    cout << maximumTime(arr);
 
    return 0;
}
// Contributed By Devendra Kolhe


Java
// Java program for the above approach
import java.util.*;
 
public class GFG{
     
    static class pair
    {
        int first, second, third;
          
        pair(int first,int second,int third)
        {
             this.first = first;
             this.second = second;
             this.third = third;
        }
    }
     
    // Direction arrays
    static int direction[][] = { { 1, 0 }, { 0, -1 },
                            { -1, 0 }, { 0, 1 } };
     
    // Function to find the maximum time
    // required for all patients to get infected
    static int maximumTime(int arr[][])
    {
        // Stores the number of rows
        int n = arr.length;
     
        // Stores the number of columns
        int m = arr[0].length;
     
        // Stores wether particular index(i, j)
        // is visited or not
        boolean visited[][] = new boolean[n][m];
     
        // Stores index and time of
        // infection of infected persions
        Queue q = new LinkedList<>();
     
        //Stores uninfected patients count
        int uninfected_count=0;
         
        //Stores time at which last person got infected
        int time = 0;
        // Traverse the matrix
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
     
                // If the current patient
                // is already infected
                if (arr[i][j] == 2) {
     
                    // Push the index of current patient
                    // and mark it as visited
                    q.add( new pair(i, j, 0 ));
                    visited[i][j] = true;
                }
             
                //If current patient is uninfected
                //increment uninfected count
                if(arr[i][j] == 1){
                    uninfected_count++;
                }
            }
        }
     
        // Iterate until queue becomes empty
        while (!q.isEmpty()) {
            // Stores the front element of queue
            pair current = q.peek();
             
            time = current.third;
            // Pop out the front element
            q.poll();
     
            // Check for all four
            // adjacent indices
            for (int[] it : direction) {
     
                // Find the index of the
                // adjacent cell
                int i = current.first
                        + it[0];
                int j = current.second
                        + it[1];
     
                // If the current adjacent
                // cell is invalid or it
                // contains an infected patient
                if (i < 0 || j < 0 || i >= n
                    || j >= m || arr[i][j] != 1
                    || visited[i][j]) {
     
                    // Continue to the next
                    // neighbouring cell
                    continue;
                }
     
                // Push the infected
                // neighbour into queue
                q.add( new pair( i, j, time + 1 ));
                visited[i][j] = true;
                uninfected_count--;
            }
        }
     
        // If an uninfected patient is present
        if (uninfected_count != 0)
            return -1;
     
        // Return the final result
        return time;
    }
     
    // Driver Code
    public static void main(String args[])
    {
        int arr[][] = { { 2, 1, 0, 2, 1 },
                    { 1, 0, 1, 2, 1 },
                    { 1, 0, 0, 2, 1 } };
                     
        System.out.println(maximumTime(arr));
     
    }
}
 
// This code is contributed by adityapande88.


输出
2

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

方法 2 :这使用相同的 BFS 遍历技术,但不是使用整数数组来跟踪是否所有患者都被感染,而是使用单个整数,这减少了整体空间消耗和对未感染患者进行额外检查的开销。

基本思想是我们将在开始时存储未感染者的数量,并且当一个人被感染时,我们将减少这个数量。这将消除最后检查未感染者的开销。最后一个人被感染的时间将是我们的最终答案。

C++

// C++ program for the above approach
#include 
using namespace std;
 
// Direction arrays
vector > direction
    = { { 1, 0 }, { 0, -1 }, { -1, 0 }, { 0, 1 } };
 
// Function to find the maximum time
// required for all patients to get infected
int maximumTime(vector > arr)
{
    // Stores the number of rows
    int n = arr.size();
 
    // Stores the number of columns
    int m = arr[0].size();
 
    // Stores wether particular index(i, j)
    // is visited or not 
    vector> visited(n,vector(m,0));
 
    // Stores index and time of
    // infection of infected persions
    queue, int> > q;
   
    //Stores uninfected patients count 
      int uninfected_count=0;
     
      //Stores time at which last person got infected
      int time = 0;
    // Traverse the matrix
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
 
            // If the current patient
            // is already infected
            if (arr[i][j] == 2) {
 
                // Push the index of current patient
                // and mark it as visited
                q.push({ { i, j }, 0 });
                visited[i][j] =  1;
            }
           
            //If current patient is uninfected
              //increment uninfected count
              if(arr[i][j] == 1){
                uninfected_count++;
            }
        }
    }
 
    // Iterate until queue becomes empty
    while (!q.empty()) {
        // Stores the front element of queue
        pair, int> current
            = q.front();
           
        time = current.second;
        // Pop out the front element
        q.pop();
 
        // Check for all four
        // adjacent indices
        for (auto it : direction) {
 
            // Find the index of the
            // adjacent cell
            int i = current.first.first
                    + it.first;
            int j = current.first.second
                    + it.second;
 
            // If the current adjacent
            // cell is invalid or it
            // contains an infected patient
            if (i < 0 || j < 0 || i >= n
                || j >= m || arr[i][j] != 1
                || visited[i][j] != 0) {
 
                // Continue to the next
                // neighbouring cell
                continue;
            }
 
            // Push the infected
            // neighbour into queue
            q.push({ { i, j }, time + 1 });
            visited[i][j] = 1;
              uninfected_count--;
        }
    }
 
    // If an uninfected patient is present
    if (uninfected_count != 0)
        return -1;
 
      // Return the final result
    return time;
}
 
// Driver Code
int main()
{
    vector > arr
        = { { 2, 1, 0, 2, 1 },
            { 1, 0, 1, 2, 1 },
            { 1, 0, 0, 2, 1 } };
    cout << maximumTime(arr);
 
    return 0;
}
// Contributed By Devendra Kolhe

Java

// Java program for the above approach
import java.util.*;
 
public class GFG{
     
    static class pair
    {
        int first, second, third;
          
        pair(int first,int second,int third)
        {
             this.first = first;
             this.second = second;
             this.third = third;
        }
    }
     
    // Direction arrays
    static int direction[][] = { { 1, 0 }, { 0, -1 },
                            { -1, 0 }, { 0, 1 } };
     
    // Function to find the maximum time
    // required for all patients to get infected
    static int maximumTime(int arr[][])
    {
        // Stores the number of rows
        int n = arr.length;
     
        // Stores the number of columns
        int m = arr[0].length;
     
        // Stores wether particular index(i, j)
        // is visited or not
        boolean visited[][] = new boolean[n][m];
     
        // Stores index and time of
        // infection of infected persions
        Queue q = new LinkedList<>();
     
        //Stores uninfected patients count
        int uninfected_count=0;
         
        //Stores time at which last person got infected
        int time = 0;
        // Traverse the matrix
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
     
                // If the current patient
                // is already infected
                if (arr[i][j] == 2) {
     
                    // Push the index of current patient
                    // and mark it as visited
                    q.add( new pair(i, j, 0 ));
                    visited[i][j] = true;
                }
             
                //If current patient is uninfected
                //increment uninfected count
                if(arr[i][j] == 1){
                    uninfected_count++;
                }
            }
        }
     
        // Iterate until queue becomes empty
        while (!q.isEmpty()) {
            // Stores the front element of queue
            pair current = q.peek();
             
            time = current.third;
            // Pop out the front element
            q.poll();
     
            // Check for all four
            // adjacent indices
            for (int[] it : direction) {
     
                // Find the index of the
                // adjacent cell
                int i = current.first
                        + it[0];
                int j = current.second
                        + it[1];
     
                // If the current adjacent
                // cell is invalid or it
                // contains an infected patient
                if (i < 0 || j < 0 || i >= n
                    || j >= m || arr[i][j] != 1
                    || visited[i][j]) {
     
                    // Continue to the next
                    // neighbouring cell
                    continue;
                }
     
                // Push the infected
                // neighbour into queue
                q.add( new pair( i, j, time + 1 ));
                visited[i][j] = true;
                uninfected_count--;
            }
        }
     
        // If an uninfected patient is present
        if (uninfected_count != 0)
            return -1;
     
        // Return the final result
        return time;
    }
     
    // Driver Code
    public static void main(String args[])
    {
        int arr[][] = { { 2, 1, 0, 2, 1 },
                    { 1, 0, 1, 2, 1 },
                    { 1, 0, 0, 2, 1 } };
                     
        System.out.println(maximumTime(arr));
     
    }
}
 
// This code is contributed by adityapande88.
输出
2

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live