【8月刷题打卡】求细胞数量

205 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情

求细胞数量

题目描述

一矩形阵列由数字 0099 组成,数字 1199 代表细胞,细胞的定义为沿细胞数字上下左右若还是细胞数字则为同一细胞,求给定矩形阵列的细胞个数。

输入格式

第一行两个整数代表矩阵大小 nnmm

接下来 nn 行,每行一个长度为 mm 的只含字符 09 的字符串,代表这个 n×mn \times m 的矩阵。

输出格式

一行一个整数代表细胞个数。

样例 #1

样例输入 #1

4 10
0234500067
1034560500
2045600671
0000000089

样例输出 #1

4

提示

数据规模与约定

对于 100%100\% 的数据,保证 1n,m1001 \le n,m \le 100

问题为求有多少个不包含0的极大连通块。 按照顺序枚举每一个点,在枚举到一个点时,如果他值不 为0且没有被访问过,说明他不属于之前的任意一个连通块,给 答案加一。 之后将这个点放入队列中并标记为访问过,作为开始的唯一 一项,之后进行bfs。 bfs时依次枚举队列中的每一项,再枚举当前项的所有后继 节点,如果没有被访问过,则加入队列并标记为访问过。

#include<iostream>
using namespace std;
struct zuobiao{
	int x,y;
}q[30000];
bool map[200][200],p[200][200];//图用bool二维数组储存
int n,m,ans;
char a;
int c[4][2]={0,1,1,0,-1,0,0,-1};//数组储存四个方向
void bfs(int x,int y)
{
	ans++;//新的细胞
	int f=0,r=1,X,Y;//f:队首  r:队尾
	q[1].x=x;
	q[1].y=y;
	while(f<r)
	{
		f++;//入队
		X=q[f].x,Y=q[f].y;
		p[X][Y]=1;//标记已走过
		for(int i=0;i<4;i++)//循环四个方向
		{
			int xx=X+c[i][0];
			int yy=Y+c[i][1];
			if(map[xx][yy]&&(!p[xx][yy]))//是数字且没走过
            //(边界以外都为0,所以可以不用判断边界)
			{
				q[++r].x=xx;//加入队尾等待处理
				q[r].y=yy;
			}
		}
	}
}
int main()
{
	cin>>m>>n;
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>a;
			map[i][j]=(a!='0');//存储到bool数组中
		}
	}
	for(int i=1;i<=m;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(!p[i][j]&&map[i][j])
			{
				bfs(i,j);//如果没被搜索过且是数字,BFS
			}
		}
	}
	cout<<ans;
}