目录

背景介绍

BFS实现

基本思想

获取相邻位置元素技巧

BFS函数

DFS实现

基本思想

DFS函数

完整代码

背景介绍

背景

给出一个mxn的矩阵,矩阵中的元素为0或1。称位置(x,y)与其上下左右四个位置(x,y+1),(x,y-1),(x-1,y),(x+1,y)是相邻的。如果矩阵中有若干(可以是1)个1是相邻的(不必两两相邻),那么称这些1构成了一个“块”。求给定的矩阵中“块”的个数。

例子

0 1 1 1 0 0 1
0 0 1 0 0 0 0
0 0 0 0 1 0 0
0 0 0 1 1 1 0
1 1 1 0 1 0 0
1 1 1 1 0 0 0

上面给定的6x7的矩阵中块的个数是4。

BFS实现

基本思想

枚举每一个位置的元素,如果为0,则跳过;如果为1,则使用BFS查询与该位置相邻的4个位置(前提是不出界),判断它们是否为1(如果某个相邻的位置为1,则同样去查询与该位置相邻的4个位置,直到整个“1”块访问完毕)。而为了防止走回头路,一般可以设置一个bool型数组inq(即in queue的简写)来记录每个位置是否在BFS中已入过队(不是是否已被访问)

获取相邻位置元素技巧

增量数组+遍历

int X[] = {0,0,-1,1};
int Y[] = {1,-1,0,0};for(int i=0;i<4;i++){newX = nowX + X[i];newY = nowY + Y[i];
}

BFS函数

//BFS的作用是访问(x,y)所在块中的所有结点
//具体访问操作是将inq[x][y]设置为1
void BFS(int x,int y){queue<Node> que;node.x = x,node.y = y;//当前节点的坐标是(x,y)que.push(node);//头结点入队inq[x][y] = true;//设置已经入队while(!que.empty()){Node top = que.front();//取出队首元素que.pop();//队首元素出队for(int i=0;i<4;i++){int newX = top.x + X[i];int newY = top.y + Y[i];if(judge(newX,newY)){//如果该邻居节点可以入队 node.x = newX;node.y = newY;que.push(node);//入队inq[newX][newY] = true;//设置已经入队 }} }
} 

DFS实现

基本思想

DFS和BFS函数的作用相同。只不过不再需要队列,而是使用递归。关键步骤是,遇到符合要求的邻居结点,进一步看邻居的邻居是否符合要求。

DFS函数

//DFS的作用是访问(x,y)所在块中的所有节点
//具体访问操作是将inq[x][y]设置为1
void DFS(int x,int y){inq[x][y] = true;//设置(x,y)被访问过for(int i=0;i<4;i++){int newX = x + X[i];int newY = y + Y[i];if(judge(newX,newY)){//如果该邻居节点可以入队 inq[newX][newY] = true;DFS(newX,newY);//进一步搜索邻居的邻居 }}
} 

完整代码

#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>using namespace std;const int maxn = 100;struct Node{int x,y;//坐标(x,y)
}node;int n,m;//矩阵的大小是n*m
int matrix[maxn][maxn];//01矩阵
bool inq[maxn][maxn] =  {false};//初始化为全部没入过队列
int X[4] = {0,0,-1,1};//增量数组
int Y[4] = {1,-1,0,0};  bool judge(int x,int y){//判断位置(x,y)是否可以入队//越界,不入if(x>=n||x<0||y>=m||y<0)return false;//为0,不入 if(!matrix[x][y])return false;//已经入过,不入if(inq[x][y])return false;return true;
}//BFS的作用是访问(x,y)所在块中的所有结点
//具体访问操作是将inq[x][y]设置为1
void BFS(int x,int y){queue<Node> que;node.x = x,node.y = y;//当前节点的坐标是(x,y)que.push(node);//头结点入队inq[x][y] = true;//设置已经入队while(!que.empty()){Node top = que.front();//取出队首元素que.pop();//队首元素出队for(int i=0;i<4;i++){int newX = top.x + X[i];int newY = top.y + Y[i];if(judge(newX,newY)){//如果该邻居节点可以入队 node.x = newX;node.y = newY;que.push(node);//入队inq[newX][newY] = true;//设置已经入队 }} }
}//DFS的作用是访问(x,y)所在块中的所有节点
//具体访问操作是将inq[x][y]设置为1
void DFS(int x,int y){inq[x][y] = true;//设置(x,y)被访问过for(int i=0;i<4;i++){int newX = x + X[i];int newY = y + Y[i];if(judge(newX,newY)){//如果该邻居节点可以入队 inq[newX][newY] = true;DFS(newX,newY);//进一步搜索邻居的邻居 }}
} int main(){scanf("%d%d",&n,&m);for(int x=0;x<n;x++){for(int y=0;y<m;y++){scanf("%d",&matrix[x][y]);}}int num = 0;//块数for(int x=0;x<n;x++){for(int y=0;y<m;y++){//如果元素为1且没如果队,那就是发现了一个新块 if(matrix[x][y]&&!inq[x][y]){num ++;DFS(x,y);} }} printf("%d\n",num); return 0;
}

分别用BFS和DFS求给定的矩阵中“块”的个数相关推荐

  1. 拓扑排序【Kahn算法(bfs)和dfs求拓扑序列及判环】

    拓扑排序 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,该排序满足这样的条件--对于图中的任意两个结点u和v,若存在一条有 ...

  2. c语言编程矩阵主对角线相同,急求!c语言 求N*N矩阵中主对角线和次对角线的元素之和...

    急求!c语言 求N*N矩阵中主对角线和次对角线的元素之和 來源:互聯網  2010-02-24 23:29:06  評論 分類: 電腦/網絡 >> 程序設計 >> 其他編程語言 ...

  3. ajax参数中字符串最大长度_6.7 C++数组名作函数参数 | 求3*4矩阵中最大的值

    C++用数组元素作函数实参 C++中实参可以是表达式,而数组元素可以是表达式的组成部分,因此数组元素可以作为函数的实参,与用变量作实参一样,将数组元素的值传送给形参变量. C++也可以用数组名作函数参 ...

  4. 分别采用递归和非递归方式编写两个函数,求一棵二叉树中叶子节点个数

    分别采用递归和非递归方式编写两个函数,求一棵二叉树中叶子节点个数 #include #include #define MAXSIZE 50 typedef char datatype; typedef ...

  5. 链接:https://ac.nowcoder.com/acm/problem/22228来源:牛客网题目描述 在给定的数组中删除一个数。输入描述:多组测试。每组第一行输入1个整数n(n

    链接:登录-专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 在给定的数组中删除一个数. 输入描述: 多组测试. 每组第一行输入1个整数n(n<20), 第二行输入n个整数 第三行输入1 ...

  6. R7-3 统计满足特定条件的字符数​输入字符串A(没有重复字符),输入字符串B,求在字符串A中字符的个数,这些字符必须同时又在字符串B中。提示:用in运算符。输入格式:一行输入字符串A。一行

    输入字符串A(没有重复字符),输入字符串B,求在字符串A中字符的个数,这些字符必须同时又在字符串B中.提示:用in运算符. 输入格式: 一行输入字符串A. 一行输入字符串B. 输出格式: 一行输出字符 ...

  7. 转:对于一个字节(8bit)的变量,求其二进制表示中“1”的个数

    转:http://toutiao.com/a4280977370/ [解法一] 可以举一个八位的二进制例子来进行分析.对于二进制操作,我们知道,除以一个 2,原来的数字将会减少一个0.如果除的过程中有 ...

  8. 求两个矩阵中向量的欧氏距离(python实现)

    假设有两个三维向量集,用矩阵表示: 要求A,B两个集合中的元素两两间欧氏距离. 先求出ABT: 然后对A和BT分别求其中每个向量的模平方,并扩展为2*3矩阵: 将上面这个矩阵一开平方,就得到了A,B向 ...

  9. 求1到100中9的个数

    个位9的数目+十位9的数目 #include<stdio.h> int main() {int num = 0;int count = 0;for (num = 1; num <= ...

最新文章

  1. Java后端进行经纬度点抽稀聚合,HTML呈现及前端聚合实现点聚合~
  2. 接口学习笔记(2009.11.24)
  3. Web服务的性能测试
  4. 【UVA1638】杆子的排列
  5. 整个行业都缺Web前端工程师,你还在问Web前端工作好找吗?
  6. 在两个不同域中的WINDOWS 2003活动目录做迁移笔记
  7. SQL Server中的查询优化技术:提示和技巧
  8. c语言基础知识 面试,c语言面试最必考的十道试题,求职必看!!!
  9. 【论文写作】JSP旅游网如何写概念设计
  10. [转载] 如何用一个Python示例入门TensorFlow?
  11. 车牌识别LPR(八)-- 字符识别
  12. PyQt5的笔记(中-1)
  13. windows 使用ACR122U-A9设备读写M1卡
  14. 【重识云原生】第四章云网络第二节——相关基础知识准备
  15. Django入门教程
  16. 联通pt952g 光猫管理员密码获取
  17. Word文档docx的图标显示异常,doc的显示正常,但是可以用,解决办法
  18. word 中巧妙添加分隔线
  19. python知识点大全-2
  20. 区块链中的epoch

热门文章

  1. 是否可以人为修改发表时间
  2. 深入浅出开源性能测试工具 Locust (使用篇 1)
  3. WIN7 64位系统下,右下角的声音和电源图标不见的解决办法
  4. onchange事件只生效一次的问题
  5. 如何彻底卸载mysql(xp)
  6. Nutch插件开发及发布流程
  7. 数据库开发个人总结(ADO.NET小结)
  8. 利用 JQuery的load函数动态加载页面
  9. 快过年了,为过完年跳槽的人准备一份面试题
  10. 范登读书解读《亲密关系》(婚姻、爱情) 笔记