📌  相关文章
📜  检查网格中编号为 1 到 K 的单元格在删除最多一个阻塞单元格后是否可以连接

📅  最后修改于: 2021-10-25 03:15:18             🧑  作者: Mango

给定一个大小为N*M的网格AK 个单元组成,由范围[1, 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


Javascript


输出:
Yes

性能分析:

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