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

📅  最后修改于: 2021-04-17 15:04:22             🧑  作者: Mango

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

例子:

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

  • 初始化一个二维数组,将timeofinfection [] []设为-1 ,以便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;
}


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


输出
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
输出
2