求细胞数量
题目描述
一矩形阵列由数字 0 0 0 到 9 9 9 组成,数字 1 1 1 到 9 9 9 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。
输入格式
第一行两个整数代表矩阵大小 n n n 和 m m m。
接下来
n
n
n 行,每行一个长度为
m
m
m 的只含字符 0
到 9
的字符串,代表这个
n
×
m
n \times m
n×m 的矩阵。
输出格式
一行一个整数代表细胞个数。
样例 #1
样例输入 #1
4 10
0234500067
1034560500
2045600671
0000000089
样例输出 #1
4
提示
数据规模与约定
对于 100 % 100\% 100% 的数据,保证 1 ≤ n , m ≤ 100 1 \le n,m \le 100 1≤n,m≤100。
##题解
这是一类求连通块的题目,被0包围的非零数组成的块就是一个细胞,可以使用dfs和bfs的方法来求解,这里展示dfs的求解过程。
首先在输入的时候,此题目输入的是一串数字,为了把它分割成每一个数字存入数组,采用设置一个中间变量char c来做衔接,每次cin一个字符,再把这一个字符转化成数字,通过减去0字符的ASCII值来转换成数字
for (int i = 0; i <n; i++) {
for (int j = 0; j <m; j++) {
char c;
cin>>c;
a[i][j] = c-'0';
}
}
思路是先设置一个v数组用来标记是否访问过,一个sum值来记录细胞数,使用一个for循环来遍历每一个位置,如果没有访问过且这个位置不是0(即是细胞数字)时调用dfs遍历,然后不断递归调用,递归栈中不断堆砌,在每一次完成一个块的搜索的时候,即从主dfs中出来的时候记录细胞数量,sum++即可。
主函数区域:
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
if (v[i][j] == 0 && a[i][j] != 0) {
dfs(i, j);
sum++;
}
}
}
再来解释dfs函数如何写,传入x和y的位置信息,首先定义出界条件,当x和y位置出界或者当前访问块已访问过(v标记为1)或者当前访问数字为0的时候跳出当前dfs函数,使用return,注意在迷宫问题中终止函数需要使用exit(0)。
当符合递归条件的时候,分别向四个方向探索,分别调用四次dfs函数即可层层递归。
void dfs(int x, int y) {
if (x>n-1||y>m-1||a[x][y] == 0||v[x][y]==1) {
return;
}
else {
v[x][y] = 1;//标记已访问
dfs(x, y + 1);
dfs(x + 1, y);
dfs(x, y - 1);
dfs(x - 1, y);
}
}
下面展示全部代码:
int n, m; int a[105][105]; int v[105][105] = {0};
int sum = 0;
void dfs(int x, int y) {
if (x>n-1||y>m-1||a[x][y] == 0||v[x][y]==1) {
return;
}
else {
v[x][y] = 1;//标记已访问
dfs(x, y + 1);
dfs(x + 1, y);
dfs(x, y - 1);
dfs(x - 1, y);
}
}
int main() {
cin >> n >> m;
for (int i = 0; i <n; i++) {
for (int j = 0; j <m; j++) {
char c;
cin>>c;
a[i][j] = c-'0';
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (v[i][j] == 0 && a[i][j] != 0) {
dfs(i, j);
sum++;
}
}
}
cout << sum;
}
洛谷亲测已AC,小白第一次发布题解,有问题欢迎讨论~