广度优先搜索遍历2-一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞

例8.2
一矩形阵列由数字0到9组成,数字1到9代表细胞,细胞的定义为沿细胞数字上下左右还是细胞数字则为同一细胞,
求给定矩形阵列的细胞个数

分析
1.从文件中读入m*n矩阵阵列,将其转换为boolean矩阵存入bz数组中
2.沿bz数组矩阵从上到下、从左到右,找到遇到的第一个细胞
3.将细胞的位置入队h,并沿其上下左右四个方向上的细胞位置入队,入对后的位置bz数组置为false
4.将h队的队头出队,沿其上下左右四个方向上的细胞位置入队,入队后的位置bz数组置为false
5.重复4中的操作,直至h队空为止,则此时找出了一个细胞
6.重复2,直至矩阵找不到细胞
7.输出找到的细胞数
#include<iostream>
#include<bits/stdc++.h>
using namespace std;

int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
int bz[100][100],num=0,n,m;

//广度优先搜索算法处理
void doit(int p,int q){
    //初始化数据
    int x,y,t,w,i;
    int h[1000][3];
    num++;
    bz[p][q]=0;
    t=0;
    w=1;
    h[1][1]=p;//遇到的第一个细胞入队
    h[1][2]=q;

    //循环遍历
    do{
        t++;//队头指针加1
        //沿细胞的上下左右四个方向搜索细胞
        for (i = 0; i <=3; ++i) {
            x=h[t][1]+dx[i];//用于移动左右位置
            y=h[t][2]+dy[i];//用于移动上下位置
            //判断该点是否可以入队
            //前四个限制条件是必须在bz数组中,
            if((x>=0)&&(x<m)&&(y>=0)&&(y<n)&&(bz[x][y])){
                w++;
                h[w][1]=x;//将需要移动的位置记录进H表中
                h[w][2]=y;
                bz[x][y]=0;//记录走过的细胞
            }//本方向搜索到细胞就入队
        }
    }while(t<w);//直至队空为止
}

//主函数
int main(){
    //初始化数据
    int i,j;
    char s[100],ch;
    scanf("%d%d\n",&m,&n);
    for (i = 0; i <=m-1 ; ++i) {//将二维数组初始化
        for (j = 0; j <=n-1 ; ++j) {
            bz[i][j]=1;
        }
    }
    for (i = 0; i <=m-1 ; ++i) {//给二维数组赋初值
        gets(s);
        for (j = 0; j <=n-1 ; ++j) {
            if(s[j]=='0'){
                bz[i][j]=0;
            }
        }
    }

    //调用BFS处理数据
    for (i = 0; i <m; ++i) {
        for (j = 0; j <n ; ++j) {
            if(bz[i][j]){
                doit(i,j);
            }
        }
    }

    //输出数据
    printf("NUMBER of cells=%d",num);

    return 0;
}

总结:

这个和上一篇文章类似,不过更复杂一点,这个需要用到纵横坐标来确定位置。比较困难的一部分还是广度优先算法doit的实现,其实只要按着图表分析也是比较容易理解的。开始我在电脑上做,虽然颜色可以多选,但是鼠标使用着不是很方便(出现错误),所以转而手工分析(正确解析),这里贴一下自己的计算过程

 

 

最后记录一下自己做题过程中出现的错误:

1.reference to 'map' is ambiguous|

c++编译出现此错误    表明定义的变量名字map和库函数map冲突而产生歧义,是因为自己引用了<bits/stdc++.h>

2.Process finished with exit code -1073741819 (0xC0000005)

这个具体的原因不清楚,但是后面我在检查的时候发现自己的二维数组写错了,也就是判断下一个是否是细胞那里写错了,所以输入样例数据后一直运行不出结果。后面修改好就可以运行了。可能是因为代码中间有语法错误或语义错误就会报这个问题。

3.是一个警告:Clang-Tidy: 'scanf' used to convert a string to an integer value, but function will not report conve

 这个问题不影响运行结果,但是有点奇怪,之前学习的时候都是使用cin或者scanf接受输入的数据,不知道为什么现在会有这种警告。网上搜了好像也没看懂。

4.学到了一个新知识——scanf“%1d”读入。

例如:scanf("%1d",&a[i][j])

但是这个东西效率不搞,可以作为了解,写算法题的时候会拖延较长时间

### 回答1: 题目描述:给定一个由数字到9组成矩形阵列,其中数字1到9代表细胞细胞定义为沿细胞数字上下左右还是细胞数字则为同一细胞,求给定矩形阵列细胞个数。 解题思路:可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来解决此问题。对于每个细胞,我们可以从它开始,向上下左右四个方向搜索,如果搜索到的数字是1到9,则说明是同一细胞,继续搜索下去。搜索过的细胞可以标记为已访问,避免重复计算。 代码实现:可以使用递归实现DFS,也可以使用队列实现BFS。以下是DFS的代码实现: ### 回答2: 题目描述:给定一个由数字0到9组成矩形阵列,其中数字1到9代表细胞细胞定义为沿细胞数字上下左右还是细胞数字则为同一细胞。请计算给定矩形阵列细胞的个数。 思路分析:此题需要通过遍历矩阵,判断每个数字是否为细胞来计算细胞的个数。具体来说,可以通过深度优先搜索或广度优先搜索实现。以深度优先搜索为例,对于每个数字为1-9的位置,从当前位置出发,搜索其上下左右四个方向,如果该方向上的数字也为1--9,那么继续搜索,否则返回。在搜索时,可以通过将已访问过的数字标记为‘0’,避免重复访问。最终,矩阵中标记为‘1’的数字个数就是细胞的个数。 代码实现: //定义方向数组 int dx[4]={1,-1,0,0}; int dy[4]={0,0,1,-1}; //DFS搜索 void dfs(vector<vector<char>>& grid,int x,int y){ int n=grid.size(); int m=grid[0].size(); //搜索完当前细胞后,将其标记为‘0’,避免重复访问 grid[x][y]='0'; for(int i=0;i<4;i++){ int nx=x+dx[i]; int ny=y+dy[i]; if(nx>=0 && nx<n && ny>=0 && ny<m && grid[nx][ny]>'0'){ dfs(grid,nx,ny); } } } int countCells(vector<vector<char>>& grid) { int n=grid.size(); int m=grid[0].size(); int res=0; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(grid[i][j]>'0'){ dfs(grid,i,j); res++; } } } return res; } 时间复杂度:O(nm) 空间复杂度:O(nm) ### 回答3: 这是一个常见的二维数组/矩阵问题,可以用深度优先搜索(DFS)或广度优先搜索(BFS)来解决。 以DFS为例,我们可以先遍历整个矩阵,遇到第一个数字为1的格子就进入DFS,依次搜索4个方向,将访问过的细胞标记为'#',直到找完与该细胞相邻的所有细胞,然后回溯到上一级,继续搜索下一个未被标记的细胞,直到整个矩阵都被遍历完为止,记录被访问的细胞个数即可。 具体实现时,可以用一个visited数组记录每个点是否已经被访问过,若访问到的点为'#'或越界或数字为0,则返回,否则继续搜索该点的四周。 以下是DFS的代码实现(C++): ``` int dfs(vector<vector<char>>& grid, int i, int j) { if (i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size() || grid[i][j] == '#' || grid[i][j] == '0') return 0; grid[i][j] = '#'; return 1 + dfs(grid, i - 1, j) + dfs(grid, i + 1, j) + dfs(grid, i, j - 1) + dfs(grid, i, j + 1); } int countCells(vector<vector<char>>& grid) { int count = 0; for (int i = 0; i < grid.size(); i++) { for (int j = 0; j < grid[0].size(); j++) { if (grid[i][j] == '1') count += dfs(grid, i, j); } } return count; } ``` 其中,grid是二维矩阵,'0'~'9'是该矩阵内的数字,'#'表示该点已经被访问过,count表示细胞个数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值