网格的探索c++

题目背景

在一个神秘的二维世界中,小可和小达是一对好朋友。他们在探索这个世界时,发现了一个由陆地和水组成的二维网格。陆地是他们可以行走的区域,而水则是他们无法通过的区域。

题目描述

小可和小达的好奇心驱使他们开始探索这个网格。他们发现,如果两个陆地单元格在水平或垂直方向上相邻,那么它们就属于同一个连通块。也就是说,如果小可和小达可以从一个陆地单元格到达另一个陆地单元格,那么他们就属于同一个连通块。 于是小可和小达开始了他们的探索,他们希望能够找到这个网格的所有陆地连通块,并计算出它们的个数。

输入格式

输入的第一行包含两个整数 nn 和 mm ,表示网格的行数和列数。

接下来的 nn 行,每行包含 mm 个整数,表示网格的每个单元格的状态。11 表示陆地,00 表示水。

输出格式

输出一个整数,表示陆地的连通块个数。

样例

输入数据 1

4 5
1 1 0 0 0
1 1 0 0 0
0 0 1 0 0
0 0 0 1 1

Copy

输出数据 1

3

Copy

提示

样例1解释

样例1 很显然有左上角、中间部分、右下角一共三个陆地连通块。

非常简单 基础连通块问题

#include<bits/stdc++.h>
using namespace std;
int n,m;
int dx[4]={0,0,1,-1};//次处为上下左右方向移动
int dy[4]={1,-1,0,0};
int vis[1001][1001];//此为标记数组
int a[1001][1001];//这是要输入的数组
int cnt=0;
void dfs(int x,int y){//使用dfs深度优先搜索 非常适用于连通块问题
	vis[x][y]=1;//每次标记不走重复
	for(int i = 0 ; i < 4 ; i++){//四个方向遍历
		int xx=x+dx[i],yy=y+dy[i];//每次更新坐标
		if(xx<1||xx>n||yy<1||yy>m||vis[xx][yy]||a[xx][yy]==0) continue;//这里用于判断是否越界是否不是1如果符合其中一项就跳过这一次
		dfs(xx,yy);//符合要求往下一个点的上下左右方向移动这就是dfs的精髓(一条路走到黑)
	}
}
int main(){
	cin >> n >> m;//输入
	for(int i = 1; i <= n ; i++){
		for(int j = 1 ; j <= m ;j++){
			cin >> a[i][j];//这里不多解释
		}
	}
	for(int i = 1; i <= n ; i++){
		for(int j = 1; j <= m ; j++){
			if(a[i][j]==1&&vis[i][j]==0){//这里后面一句很关键如果这个位置的数是1 and 这个位置没被标记过(什么意思呢就是没被搜过 不属于其他的连通块)
				cnt++;//符合以上条件就代表发现一个新连通块
				dfs(i,j);//搜索 主要目的是找出何当前a[i][j]属于同一连通块的格子进行标记 以免重复搜索造成错误
			}
		}
	}
	cout << cnt;//最后输出答案即可
}

总结:本题主要考察dfs的基础变化 核心心在于如何找到并标记属于同一个连通块的格子

代码核心在于dfs以及标记数组 此题较为简单适合dfs新手练习

dfs核心:一条路走到底 就是找到一个点就往这个点往下搜直到不能搜为止 在回溯到上一个点 非常符合递归的特点

image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值