点击查看代码
/*
给出一个n*m的矩阵(n和m都不超过100),矩阵中的元素为0或1。对于坐标(x,y)来说,定义其上下左右四个坐标与它相邻(x,y+1)、(x,y-1)、(x+1,y)、(x-1,y)
如果矩阵中有若干个1是相邻的(不必两两相邻,可以通过公用边相邻),则称这些1构成了一个块。求给定矩阵中块的个数
输入样例:
6 7
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
输出样例:
4
样例解释:在6*7矩阵中,块的个数为4
*/
/*
解题思路:
1、枚举每一个位置的元素,如果为0,则跳过。如果为1,则使用BFS查询与该位置相邻的4个位置(前提是没有超出边界),判断它们是否为1(如果某个相邻位置为1,
则使用同样的方法查询该位置相邻的4个位置,直到这个由相邻的1组成的块访问完成)
2、为了防止重复查询某个位置,设置bool inq[x][y]记录每个位置是否已经在BFS()中入过队(即已经访问过),inq全写是in queue入队
3、对于当前位置(x,y)来说,它的4个相邻位置是(x,y+1)、(x,y-1)、(x+1,y)、(x-1,y),因此设置两个增量数组,表示4个方向
int X[]={0,0,1,-1}; //竖着看就是(0,1)、(0,-1)、(1,0)、(-1,0)
int Y[]={1,-1,0,0};
for(int i=0; i<4; i++) { //for循环4次,分别获得(x,y)的上下左右位置
newX=x+X[i];
newY=y+Y[i];
}
*/
#include<cstdio>
#include<queue>
using namespace std;
#pragma warning(disable:4996)
const int maxn = 100; //矩阵行、列最多100行
struct node {
int x, y; //位置(x,y)
}Node;
int n, m; //矩阵行、列数
int matrix[maxn][maxn]; //存储n*m矩阵
bool inq[maxn][maxn] = { false }; //记录(x,y)是否已入过队(即有没有被访问过)
int X[4] = { 0,0,1,-1 }; //增量数组,求(x,y)的上下左后4个相邻位置
int Y[4] = { 1,-1,0,0 };
//判断位置(x,y)是否可以访问
bool judge(int x, int y) {
//x、y超出边界,则不可以访问
if (x >= n || x < 0 || y >= m || y < 0) return false;
//当前位置的元素值为0,或(x,y)已经入过队,则不可以访问
if (matrix[x][y] == 0 || inq[x][y] == true) return false;
//以上都不满足,则可以访问
return true;
}
//BSF()访问(x,y)所属的块,并统计块数
void BFS(int x, int y) {
queue<node> Q; //定义队列Q
Node.x = x, Node.y = y; //将(x,y)存入结点变量Node
Q.push(Node); //将结点Node入队
inq[x][y] = true; //(x,y)入过队,设为true
while (!Q.empty()) { //只要Q非空,就继续循环
node top = Q.front(); //将队首元素存入top变量
Q.pop(); //将队首元素出队,即手动删除
for (int i = 0; i < 4; i++) { //访问队首元素的4个相邻位置
int newX = top.x + X[i];
int newY = top.y + Y[i];
if (judge(newX, newY)) { //如果(newX,newY)可以访问
Node.x = newX, Node.y = newY; //将(newX,newY)存入结点变量Node
Q.push(Node); //将结点Node入队
inq[newX][newY] = true; //(newX,newY)入过队,设为true
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
for (int x = 0; x < n; x++) { //读取二维矩阵[x][y]
for (int y = 0; y < m; y++) {
scanf("%d", &matrix[x][y]);
}
}
int ans = 0; //记录二维矩阵中块的个数
for (int x = 0; x < n; x++) { //枚举二维矩阵每一个位置
for (int y = 0; y < m; y++) {
//如果(x,y)位置元素值为1,且该位置没有入过队,则可以访问
if (matrix[x][y] == 1 && inq[x][y] == false) {
ans++; //块数加一
BFS(x, y); //访问(x,y)所属的块,将该块内所有元素值为1的位置在inq[x][y]中都设为true
}
}
}
printf("%d\n", ans);
return 0;
}