题目分析
给定一幅地图,其中有水域,有陆地。被水域完全环绕的陆地是岛屿。有些岛屿上埋藏有宝藏,这些有宝藏的点也被标记出来了。本题就请你统计一下,给定的地图上一共有多少岛屿,其中有多少是有宝藏的岛屿。
输入格式:
输入第一行给出 2 个正整数 N 和 M(1<N×M≤105),是地图的尺寸,表示地图由 N 行 M 列格子构成。随后 N 行,每行给出 M 位个位数,其中 0
表示水域,1
表示陆地,2
-9
表示宝藏。
注意:两个格子共享一条边时,才是“相邻”的。宝藏都埋在陆地上。默认地图外围全是水域。
输出格式:
在一行中输出 2 个整数,分别是岛屿的总数量和有宝藏的岛屿的数量。
输入样例:
10 11
01000000151
11000000111
00110000811
00110100010
00000000000
00000111000
00114111000
00110010000
00019000010
00120000001
输出样例:
7 2
题目分析
这是一道 求连通块的题目,并需要记录特殊连通块(岛屿中埋有宝藏)的数量。
相对于以往做这类题目的解法来看,本题主要有一点不同,即 ,意为 最大值均可以取到 。
以往题目中,我是直接开一个全局数组 g[N][N]
存取图中元素,而本题若定义 ,则会超出内存限制。
这里介绍一个新的方式,即 vector<vector<int>> g
存储不定长数组。
首先开一个全局二维 vector
,再在局内开一个临时二维 vector
,局内初始化方法为 vector<vector<int>> a(n + 1, vector<int> (m + 1))
,将其复制到全局 vector
中。
其他会超出限制的数组均可以这样解决。
然后就是常规的求连通块问题。
Accept代码
#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<vector<int>> g;
vector<vector<bool>> st;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int cnt, val;
int hav_val;
void dfs(int x, int y)
{
st[x][y] = true;
if (g[x][y] > 1 && !hav_val) val ++, hav_val = 1;
for (int i = 0; i < 4; i ++)
{
int a = x + dx[i], b = y + dy[i];
if (a && a <= n && b && b <= m && !st[a][b] && g[a][b])
dfs(a, b);
}
}
int main()
{
cin >> n >> m;
vector<vector<int>> a(n + 1, vector<int> (m + 1));
vector<vector<bool>> b(n + 1, vector<bool> (m + 1));
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
{
char c; cin >> c;
a[i][j] = c - '0';
}
g = a; st = b;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
if (g[i][j] && !st[i][j])
hav_val = 0, cnt ++, dfs(i, j);
cout << cnt << ' ' << val;
return 0;
}
update:不用嵌套也能过
// dfs
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m;
vector<int> g[N], st[N];
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int cnt, val;
int u;
void dfs(int x, int y)
{
st[x][y] = true;
if (g[x][y] > 1 && !u) val ++, u = 1;
for (int i = 0; i < 4; i ++)
{
int a = x + dx[i], b = y + dy[i];
if (a && a <= n && b && b <= m && !st[a][b] && g[a][b])
dfs(a, b);
}
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++)
{
g[i].push_back(0);
st[i].push_back(0);
for (int j = 1; j <= m; j ++)
{
char c;
scanf(" %c", &c);
g[i].push_back(c - '0');
st[i].push_back(0);
}
}
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= m; j ++)
if (g[i][j] && !st[i][j])
u = 0, dfs(i, j), cnt ++;
cout << cnt << ' ' << val;
return 0;
}
// bfs
void bfs(int i, int j)
{
queue<pair<int, int>> q;
q.push({i, j}); st[i][j] = true;
while (!q.empty())
{
auto [x, y] = q.front();
q.pop();
if (!u && g[x][y] > 1) val ++, u = true;
for (int k = 0; k < 4; k ++)
{
int a = x + dx[k], b = y + dy[k];
if (a && a <= n && b && b <= m && !st[a][b] && g[a][b])
{
q.push({a, b});
st[a][b] = true;
}
}
}
}
// function 函数
function<void(int, int)> dfs = [&](int x, int y) {};
// map存图方式
map<pair<int, int>, int> p;