分别用BFS和DFS求给定的矩阵中“块”的个数
目录
背景介绍
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求给定的矩阵中“块”的个数相关推荐
- 拓扑排序【Kahn算法(bfs)和dfs求拓扑序列及判环】
拓扑排序 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,该排序满足这样的条件--对于图中的任意两个结点u和v,若存在一条有 ...
- c语言编程矩阵主对角线相同,急求!c语言 求N*N矩阵中主对角线和次对角线的元素之和...
急求!c语言 求N*N矩阵中主对角线和次对角线的元素之和 來源:互聯網 2010-02-24 23:29:06 評論 分類: 電腦/網絡 >> 程序設計 >> 其他編程語言 ...
- ajax参数中字符串最大长度_6.7 C++数组名作函数参数 | 求3*4矩阵中最大的值
C++用数组元素作函数实参 C++中实参可以是表达式,而数组元素可以是表达式的组成部分,因此数组元素可以作为函数的实参,与用变量作实参一样,将数组元素的值传送给形参变量. C++也可以用数组名作函数参 ...
- 分别采用递归和非递归方式编写两个函数,求一棵二叉树中叶子节点个数
分别采用递归和非递归方式编写两个函数,求一棵二叉树中叶子节点个数 #include #include #define MAXSIZE 50 typedef char datatype; typedef ...
- 链接:https://ac.nowcoder.com/acm/problem/22228来源:牛客网题目描述 在给定的数组中删除一个数。输入描述:多组测试。每组第一行输入1个整数n(n
链接:登录-专业IT笔试面试备考平台_牛客网 来源:牛客网 题目描述 在给定的数组中删除一个数. 输入描述: 多组测试. 每组第一行输入1个整数n(n<20), 第二行输入n个整数 第三行输入1 ...
- R7-3 统计满足特定条件的字符数输入字符串A(没有重复字符),输入字符串B,求在字符串A中字符的个数,这些字符必须同时又在字符串B中。提示:用in运算符。输入格式:一行输入字符串A。一行
输入字符串A(没有重复字符),输入字符串B,求在字符串A中字符的个数,这些字符必须同时又在字符串B中.提示:用in运算符. 输入格式: 一行输入字符串A. 一行输入字符串B. 输出格式: 一行输出字符 ...
- 转:对于一个字节(8bit)的变量,求其二进制表示中“1”的个数
转:http://toutiao.com/a4280977370/ [解法一] 可以举一个八位的二进制例子来进行分析.对于二进制操作,我们知道,除以一个 2,原来的数字将会减少一个0.如果除的过程中有 ...
- 求两个矩阵中向量的欧氏距离(python实现)
假设有两个三维向量集,用矩阵表示: 要求A,B两个集合中的元素两两间欧氏距离. 先求出ABT: 然后对A和BT分别求其中每个向量的模平方,并扩展为2*3矩阵: 将上面这个矩阵一开平方,就得到了A,B向 ...
- 求1到100中9的个数
个位9的数目+十位9的数目 #include<stdio.h> int main() {int num = 0;int count = 0;for (num = 1; num <= ...
最新文章
- Java后端进行经纬度点抽稀聚合,HTML呈现及前端聚合实现点聚合~
- 接口学习笔记(2009.11.24)
- Web服务的性能测试
- 【UVA1638】杆子的排列
- 整个行业都缺Web前端工程师,你还在问Web前端工作好找吗?
- 在两个不同域中的WINDOWS 2003活动目录做迁移笔记
- SQL Server中的查询优化技术:提示和技巧
- c语言基础知识 面试,c语言面试最必考的十道试题,求职必看!!!
- 【论文写作】JSP旅游网如何写概念设计
- [转载] 如何用一个Python示例入门TensorFlow?
- 车牌识别LPR(八)-- 字符识别
- PyQt5的笔记(中-1)
- windows 使用ACR122U-A9设备读写M1卡
- 【重识云原生】第四章云网络第二节——相关基础知识准备
- Django入门教程
- 联通pt952g 光猫管理员密码获取
- Word文档docx的图标显示异常,doc的显示正常,但是可以用,解决办法
- word 中巧妙添加分隔线
- python知识点大全-2
- 区块链中的epoch