C++-求细胞数量 解题思路
题目
【Horn Studio】编程专栏: 求细胞数量 解题思路
题目描述
一矩形阵列由数字0到9组成。我们把数字1到9称为细胞数字,数字0称为非细胞数字。
若一个细胞数字上、下、左、右仍是细胞数字,我们则把这些细胞数字称为同一细胞。 求给定矩形阵列中细胞的个数。
若一个细胞数字上、下、左、右仍是细胞数字,我们则把这些细胞数字称为同一细胞。 求给定矩形阵列中细胞的个数。
输入
第1行,整数m、n(m表示行,n表示列、1<=m,n<=1001<=m,n<=100)
接下来的m行表示输入的矩形阵列
接下来的m行表示输入的矩形阵列
输出
细胞的个数
样例输入 复制
4 10
0234500067
1034560500
2045600671
0000000089
样例输出 复制
4
提示
来源
思路
经典的bfs,只需要记录x,y。循环遍历每个点,碰到1~9,而且没有走过,ans++,从这个点开始搜索连着的一整块,用一个数组记录,走过的位置和连着一块的位置。
实质上就是一个找连通块的问题,把整个矩阵遍历一遍,然后把它周围八个方块与它相同的全部改成0,直到没有再和它相同的为止。用搜索来做,广搜深搜都可以。
这里推荐使用广搜(bfs),因为不怕超时然后TLE甚至WA,但是深搜代码更简洁易懂,在dfs上只需要cv四个方向代码就行了。
BFS版本代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, m, ans = 0, dx[8] = {1, -1, 0, 0}, dy[8] = {0, 0, 1, -1}, h[100013][3], zx, zy; 4 char b[103][103]; 5 bool a[103][103]; 6 7 void bfs(int x, int y) 8 { 9 ans++; 10 a[x][y] = false; 11 int head = 1, tail = 1; 12 h[1][1] = x, h[1][2] = y; 13 while (head <= tail) { 14 for (int i = 0; i < 4; i++) { 15 zx = h[head][1] + dx[i]; 16 zy = h[head][2] + dy[i]; 17 if (zx >= 1 && zx <= n && zy >= 1 && zy <= m && a[zx][zy]) { 18 tail++; 19 a[zx][zy] = false; 20 h[tail][1] = zx, h[tail][2] = zy; 21 } 22 } 23 head++; 24 } 25 } 26 27 int main() 28 { 29 cin >> n >> m; 30 for (int i = 1; i <= n; i++) 31 for (int j = 1; j <= m; j++) { 32 cin >> b[i][j]; 33 if (b[i][j] != '0') 34 a[i][j] = true; 35 else 36 a[i][j] = false; 37 } 38 39 for (int i = 1; i <= n; i++) 40 for (int j = 1; j <= m; j++) 41 if (a[i][j]) 42 bfs(i, j); 43 cout << ans << endl; 44 return 0; 45 }
DFS版本代码(十分感谢ken_dmr提供此方面代码,源码链接:(20条消息) 洛谷P1451 求细胞数量 用一道题理解DFS_ken_dmr的博客-CSDN博客)
#include<stdio.h> int m,n,ans; int cell[105][105],book[105][105]; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; void dfs(int x,int y) { book[x][y]=1; for(int i=0;i<4;i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(cell[nx][ny]==0||book[nx][ny]==1) continue; dfs(nx,ny); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%1d",&cell[i][j]); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { if(book[i][j]==0&&cell[i][j]!=0) { dfs(i,j); ans++; } } printf("%d\n",ans); return 0; }
彩蛋
:大家一定要有坚持的意识,最近难度可能会受打击。(心灵鸡汤)