C++-求细胞数量 解题思路

题目

【Horn Studio】编程专栏: 求细胞数量 解题思路

题目描述

一矩形阵列由数字0到9组成。我们把数字1到9称为细胞数字,数字0称为非细胞数字。
若一个细胞数字上、下、左、右仍是细胞数字,我们则把这些细胞数字称为同一细胞。 求给定矩形阵列中细胞的个数。

输入

第1行,整数m、n(m表示行,n表示列、1<=m,n<=1001<=m,n<=100)
接下来的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;
}

彩蛋

:大家一定要有坚持的意识,最近难度可能会受打击。(心灵鸡汤)

 

posted @ 2022-03-27 09:15  冯子坤  阅读(511)  评论(0编辑  收藏  举报