给定一个大小为N*M的网格A由K 个单元组成,由范围[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 ,并通过其所属的组件标记每个单元格。检查是否有任何阻塞的单元格具有属于不同组件的相邻单元格。如果存在,则可以通过解锁该单元来进行连接。否则,这是不可能的。
例子:
After performing BFS and labeling the cells by their no of components, the array appears as follows:
A={{1, 1, 1, 1}, {1, -1, -1, 1}, {-1, 2, 2, -1}, {-1, -1, -1, -1}}
The number of different label around the cell (2, 2) is 2.
Hence, unblocking it will connect the K cells.
下面是上述方法的实现:
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)