📜  移除至少一个阻塞的电池后,检查网格中编号为1到K的电池是否可以连接

📅  最后修改于: 2021-06-25 20:26:20             🧑  作者: Mango

给定一个大小为N * M的网格A ,该网格A由范围为[1,K]的值表示的K个单元格,由-1表示的一些阻塞单元格由0表示的其余未阻塞单元格组成,任务是检查是否可以连接通过解封至少一个细胞来直接或间接地使那些K细胞。只能移动到相邻的水平和垂直单元格。

例子

Input:
A = {{0, 5, 6, 0}, 
     {3, -1, -1, 4}, 
     {-1, 2, 1, -1}, 
     {-1, -1, -1, -1}},
K = 6
Output: Yes
Explanation: 
Unblocking cell (2, 2) or (2, 3) or (3, 1) or
(3, 4) would make all the K cells connected.

Input:
A = {{-1, -1, 3, -1}, 
     {1, 0, -1, -1}, 
     {-1, -1, -1, 0}, 
     {-1, 0, 2, -1}},
K = 3
Output: No
Explanation:
Atleast two cells need to be unblocked.

方法:从编号为1到K的单元格执行BFS ,并通过其所属的组件标记每个单元格。检查是否有被阻塞的单元格具有相邻的属于不同组件的单元格。如果存在,则可以通过解锁该单元来进行连接。否则,这是不可能的。

例子:

下面是上述方法的实现:

C++
// C++ implementation of the above approach
  
#include 
using namespace std;
#define pairs pair
  
void check(int k, vector > a,
           int n, int m)
{
    int cells[k][2];
    bool visited[n][m];
    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
  
            if (a[i][j] != 0
                && a[i][j] != -1) {
  
                cells[count][0] = i;
                cells[count][1] = j;
                count++;
            }
            visited[i][j] = false;
        }
    }
  
    // Arrays to make grid traversals easier
    int dx[] = { 0, 0, 1, -1 };
    int dy[] = { 1, -1, 0, 0 };
  
    // Store number of components
    int component = 0;
  
    // Perform BFS and maark every cell
    // by the component in which it belongs
    for (int i = 0; i < k; i++) {
  
        int x = cells[i][0], y = cells[i][1];
  
        if (visited[x][y])
            continue;
        component++;
        queue cells;
        cells.push(make_pair(x, y));
        visited[x][y] = true;
  
        while (!cells.empty()) {
  
            pairs z = cells.front();
            cells.pop();
            a[z.first][z.second] = component;
  
            for (int j = 0; j < 4; j++) {
  
                int new_x = z.first + dx[j];
                int new_y = z.second + dy[j];
                if (new_x < 0 || new_x >= n
                    || new_y < 0 || new_y >= m)
                    continue;
                if (visited[new_x][new_y]
                    || a[new_x][new_y] == -1)
                    continue;
  
                cells.push(make_pair(new_x, new_y));
                visited[new_x][new_y] = true;
            }
        }
    }
  
    int maximum = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
  
            if (a[i][j] == -1) {
                unordered_set set;
                for (int kk = 0; kk < 4; kk++) {
  
                    int xx = i + dx[kk];
                    int yy = j + dy[kk];
                    if (xx < 0 || xx >= n
                        || yy < 0 || yy >= m)
                        continue;
  
                    // if the cell doesn't
                    // belong to any component
                    if (a[xx][yy] <= 0)
                        continue;
                    set.insert(a[xx][yy]);
                }
                int s = set.size();
                maximum = max(s, maximum);
            }
        }
    }
  
    if (maximum == component) {
        cout << "Yes\n";
    }
    else {
        cout << "No\n";
    }
}
int main()
{
    int k = 6;
    int n = 4, m = 4;
    vector > a
        = { { 0, 5, 6, 0 },
            { 3, -1, -1, 4 },
            { -1, 2, 1, -1 },
            { -1, -1, -1, -1 } };
  
    check(k, a, n, m);
    return 0;
}


Java
// Java implementation of the above approach
import java.util.*;
  
class GFG{
    static class pair
    { 
        int first, second; 
        public pair(int first, int second)  
        { 
            this.first = first; 
            this.second = second; 
        }    
    } 
static void check(int k, int [][]a,
           int n, int m)
{
    int [][]cell = new int[k][2];
    boolean [][]visited = new boolean[n][m];
    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
   
            if (a[i][j] != 0
                && a[i][j] != -1) {
   
                cell[count][0] = i;
                cell[count][1] = j;
                count++;
            }
            visited[i][j] = false;
        }
    }
   
    // Arrays to make grid traversals easier
    int dx[] = { 0, 0, 1, -1 };
    int dy[] = { 1, -1, 0, 0 };
   
    // Store number of components
    int component = 0;
   
    // Perform BFS and maark every cell
    // by the component in which it belongs
    for (int i = 0; i < k; i++) {
   
        int x = cell[i][0], y = cell[i][1];
   
        if (visited[x][y])
            continue;
        component++;
        Queue cells = new LinkedList<>();
        cells.add(new pair(x, y));
        visited[x][y] = true;
   
        while (!cells.isEmpty()) {
   
            pair z = cells.peek();
            cells.remove();
            a[z.first][z.second] = component;
   
            for (int j = 0; j < 4; j++) {
   
                int new_x = z.first + dx[j];
                int new_y = z.second + dy[j];
                if (new_x < 0 || new_x >= n
                    || new_y < 0 || new_y >= m)
                    continue;
                if (visited[new_x][new_y]
                    || a[new_x][new_y] == -1)
                    continue;
   
                cells.add(new pair(new_x, new_y));
                visited[new_x][new_y] = true;
            }
        }
    }
   
    int maximum = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
   
            if (a[i][j] == -1) {
                HashSet set = new HashSet();
                for (int kk = 0; kk < 4; kk++) {
   
                    int xx = i + dx[kk];
                    int yy = j + dy[kk];
                    if (xx < 0 || xx >= n
                        || yy < 0 || yy >= m)
                        continue;
   
                    // if the cell doesn't
                    // belong to any component
                    if (a[xx][yy] <= 0)
                        continue;
                    set.add(a[xx][yy]);
                }
                int s = set.size();
                maximum = Math.max(s, maximum);
            }
        }
    }
   
    if (maximum == component) {
        System.out.print("Yes\n");
    }
    else {
        System.out.print("No\n");
    }
}
  
public static void main(String[] args)
{
    int k = 6;
    int n = 4, m = 4;
    int [][]a
        = { { 0, 5, 6, 0 },
            { 3, -1, -1, 4 },
            { -1, 2, 1, -1 },
            { -1, -1, -1, -1 } };
   
    check(k, a, n, m);
}
}
  
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation of the above approach
from collections import deque as queue
def check(k, a, n, m):
  
    cells = [[0 for i in range(2)] for i in range(k)]
    visited = [[0 for i in range(m)] for i in range(n)]
    count = 0
    for i in range(n):
        for j in range(m):
  
            if (a[i][j] != 0
                and a[i][j] != -1):
  
                cells[count][0] = i
                cells[count][1] = j
                count += 1
  
            visited[i][j] = False
  
    # Arrays to make grid traversals easier
    dx = [0, 0, 1, -1]
    dy = [1, -1, 0, 0]
  
    # Store number of components
    component = 0
  
    # Perform BFS and maark every cell
    # by the component in which it belongs
    for i in range(k):
  
        x = cells[i][0]
        y = cells[i][1]
  
        if (visited[x][y]):
            continue
        component += 1
        cell = queue()
        cell.append([x, y])
        visited[x][y] = True
  
        while (len(cell) > 0):
  
            z = cell.popleft()
            a[z[0]][z[1]] = component
  
            for j in range(4):
  
                new_x = z[0] + dx[j]
                new_y = z[1] + dy[j]
                if (new_x < 0 or new_x >= n
                    or new_y < 0 or new_y >= m):
                    continue
                if (visited[new_x][new_y]
                    or a[new_x][new_y] == -1):
                    continue
  
                cell.append([new_x, new_y])
                visited[new_x][new_y] = True
  
    maximum = 0
    for i in range(n):
        for j in range(m):
  
            if (a[i][j] == -1):
                se = dict()
                for kk in range(4):
  
                    xx = i + dx[kk]
                    yy = j + dy[kk]
                    if (xx < 0 or xx >= n
                        or yy < 0 or yy >= m):
                        continue
  
                    # if the cell doesn't
                    # belong to any component
                    if (a[xx][yy] <= 0):
                        continue
                    se[a[xx][yy]] = 1
  
                s = len(se)
                maximum = max(s, maximum)
  
    if (maximum == component):
        print("Yes\n")
  
    else:
        print("No\n")
  
# Driver code
if __name__ == '__main__':
    k = 6
    n = 4
    m = 4
    a=[[0, 5, 6, 0 ],
    [3, -1, -1, 4],
    [-1, 2, 1, -1],
    [-1, -1,-1,-1]]
  
    check(k, a, n, m)
  
# This code is contributed by mohit kumar 29


C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
  
class GFG{
    class pair
    { 
        public int first, second; 
        public pair(int first, int second)  
        { 
            this.first = first; 
            this.second = second; 
        }    
    } 
static void check(int k, int [,]a,
           int n, int m)
{
    int [,]cell = new int[k,2];
    bool [,]visited = new bool[n,m];
    int count = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
    
            if (a[i, j] != 0
                && a[i, j] != -1) {
    
                cell[count, 0] = i;
                cell[count, 1] = j;
                count++;
            }
            visited[i, j] = false;
        }
    }
    
    // Arrays to make grid traversals easier
    int []dx = { 0, 0, 1, -1 };
    int []dy = { 1, -1, 0, 0 };
    
    // Store number of components
    int component = 0;
    
    // Perform BFS and maark every cell
    // by the component in which it belongs
    for (int i = 0; i < k; i++) {
    
        int x = cell[i, 0], y = cell[i, 1];
    
        if (visited[x, y])
            continue;
        component++;
        List cells = new List();
        cells.Add(new pair(x, y));
        visited[x, y] = true;
    
        while (cells.Count != 0) {
    
            pair z = cells[0];
            cells.RemoveAt(0);
            a[z.first,z.second] = component;
    
            for (int j = 0; j < 4; j++) {
    
                int new_x = z.first + dx[j];
                int new_y = z.second + dy[j];
                if (new_x < 0 || new_x >= n
                    || new_y < 0 || new_y >= m)
                    continue;
                if (visited[new_x,new_y]
                    || a[new_x, new_y] == -1)
                    continue;
    
                cells.Add(new pair(new_x, new_y));
                visited[new_x, new_y] = true;
            }
        }
    }
    
    int maximum = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
    
            if (a[i, j] == -1) {
                HashSet set = new HashSet();
                for (int kk = 0; kk < 4; kk++) {
    
                    int xx = i + dx[kk];
                    int yy = j + dy[kk];
                    if (xx < 0 || xx >= n
                        || yy < 0 || yy >= m)
                        continue;
    
                    // if the cell doesn't
                    // belong to any component
                    if (a[xx, yy] <= 0)
                        continue;
                    set.Add(a[xx, yy]);
                }
                int s = set.Count;
                maximum = Math.Max(s, maximum);
            }
        }
    }
    
    if (maximum == component) {
        Console.Write("Yes\n");
    }
    else {
        Console.Write("No\n");
    }
}
   
public static void Main(String[] args)
{
    int k = 6;
    int n = 4, m = 4;
    int [,]a
        = { { 0, 5, 6, 0 },
            { 3, -1, -1, 4 },
            { -1, 2, 1, -1 },
            { -1, -1, -1, -1 } };
    
    check(k, a, n, m);
}
}
   
// This code is contributed by 29AjayKumar


输出:
Yes

性能分析:

  • 时间复杂度:在矩阵上执行BFS需要O(N * M)时间和O(N * M)时间来检查每个阻塞的单元。因此,总体时间复杂度将为O(N * M)
  • 辅助空间复杂度: O(N * M)

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。