41.岛屿数量(第四期模拟笔试)(BFS练习题)


41.岛屿数量(第四期模拟笔试)(BFS练习题)

原创 已于 2023-10-16 17:16:59 修改 · 粉丝可见 · 288 阅读 · 0 · 0 · 本内容遵循CC 4.0 BY-SA版权协议 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 · 编辑
文章链接:https://blog.csdn.net/hacker_51/article/details/132650363

链接: 卡码网KamaCoder

题目:

给定一个 m 行 n 列的二维地图,初始化每个单元格都是海洋,二维地图外也全是海洋。

操作 addLand 会将单元格(col, row)变为陆地。

定义一系列相连的被海洋包围的陆地为岛屿,

横向相邻或者纵向相连的岛屿才算相连(斜着相邻的不算)。

现有一系列的 addLand 操作,给出每次 addLand 操作后岛屿的个数。

样例:

cobol<br/>3<br/>3<br/>4<br/>0 0<br/>0 1<br/>1 2<br/>2 1<br/>
1 1 2 3

思路:

根据题意,我们是要找到 连通块有多少个,就是多少个岛屿。

由于数据范围较小,所以我们可以使用BFS搜索,每一次放生成大陆后直接暴力查找连通块输出即可,而 非法坐标的情况,我们可以直接忽略。

代码详解如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <iostream>
#include <queue>
#include <cstring>
#define endl '\n'
#define x first
#define y second
#define mk make_pair
#define YES puts("YES")
#define NO puts("NO")
#pragma GCC optimize(3,"Ofast","inline")
#define ___G std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0)
using namespace std;
const int N = 500;

using PII = pair<int,int>;

// 控制查找的时候走动的方向
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

int n,m; // 地图大小
bool g[N][N]; // 地图内容
bool vis[N][N]; // 查找的时候标记是否查找过
int k; // 操作数

int ans; // ans 是检查岛屿结果

// 查找走动方向
inline bool isRun(int x,int y)
{
return (x >= 0 && x < n && y >= 0 && y < m && !vis[x][y] && g[x][y]);
}

inline void BFS(int x,int y)
{
// 存储检查坐标
queue<PII>q;
q.push(mk(x,y));

while(q.size())
{
// 取出当前坐标
auto now = q.front();
q.pop();

// 标记已检查大陆坐标
vis[now.x][now.y] = true;

// 开始尝试往上下左右四个方向
// 寻找大陆所形成的岛屿
for(int i = 0;i < 4;++i)
{

// 取出下一步检查的坐标
int bx = now.x + dx[i];
int by = now.y + dy[i];

// 判断是否符合检查走动的条件
if(isRun(bx,by))
{
// 符合则开始标记
vis[bx][by] = true;

// 列入下一步检查点
q.push(mk(bx,by));
}
}
}
return ;
}


inline void solve()
{
// 控制输出格式
bool st = false;

cin >> n >> m >> k;

while(k--)
{
// 开始放置大陆
int x,y;
cin >> x >> y;

// 控制的空格输出格式
if(st) putchar(' ');

// 如果坐标合法,那么开始放置大陆
if(x >= 0 && x < n && y >= 0 && y < m)
{
// 每次放置大陆的时候,我们都要重新
// BFS 一遍查找连通块,所以这里要初始化标记
ans = 0;
memset(vis,false,sizeof vis);

// 放置大陆
g[x][y] = true;

for(int i = 0;i < n;++i)
{
for(int j = 0;j < m;++j)
{
// 如果该大陆没被检查过
if(!vis[i][j] && g[i][j])
{
// 累加岛屿
++ans;
// 开始检查
BFS(i,j);
}
}
}

// 输出岛屿数量结果
cout << ans;
}else
{
// 如果做标是非法情况,那么我们直接输出上一次的检查结果
cout << ans;
}

// 控制输出格式
st = true;
}
}


int main()
{
// freopen("a.txt", "r", stdin);
// ___G;
int _t = 1;
// cin >> _t;
while (_t--)
{
solve();
}

return 0;
}

最后提交:


觉得不错的话,给点打赏吧 ୧(๑•̀⌄•́๑)૭

微信二维码

wechat pay

支付宝二维码

ali pay

41.岛屿数量(第四期模拟笔试)(BFS练习题)
http://blog.angindem.cn/2023/10/16/Angindem-CSDN博客/049_49/
作者
Angindem
发布于
2023年10月16日
许可协议