岛屿个数,bfs

本文讲述了如何使用广度优先搜索(BFS)算法在编程题目中解决岛屿识别问题,特别关注如何区分外岛和环岛,以及如何在C++代码中实现。关键步骤包括标记外海和岛屿,以及处理边界条件和环形结构。
摘要由CSDN通过智能技术生成

    这道题是对你bfs运用的高难度考察,这道题还有很多坑点,比如说他储存在a数组中的0和1不是常数而是字符,你还需要进一步将其转化为常数,如果做出来了因为这一点没ac就气死了,所以阅读题目的时候要认真。

     这道题难点是你怎么在储存外岛的同时能区别这个岛是不是外环岛里面的内岛。而你可以用bfs来枚举外岛外面的外海同时对其进行标记,如果外海没法和内海相连接,就说明遇到了环岛,而我们这样就不用进一步再寻找环岛内的内岛。当我们在枚举外海时遇见了岛屿,再用bfs来枚举岛屿,进行标记,知道哪些岛是连在一起的。

     这题还得注意海是可以从八个方向进行枚举的。

岛屿个数,具体代码如下:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
const int N=51;
int a[N][N];
int t,n,m;
int v1[N][N];
int v2[N][N];//两个标记数组
int ans=0;
int idx1[4]={0,0,1,-1},idy1[4]={1,-1,0,0};
int idx2[8]={0,0,1,-1,1,1,-1,-1},idy2[8]={1,-1,0,0,1,-1,-1,1};

bool check(int x,int y)
{
	if(x>=0&&y>=0&&x<n&&y<m)
	return true;
	return false;
}
void bfs1(int x,int y)
{
       queue<pair<int,int>>	q;
       q.push({x,y});
	   v1[x][y]=1;
	   while(q.size())
	   {
	   	auto t=q.front();
	   	q.pop();
	   	for(int i=0;i<4;i++)
	   	{
	   		int xx=t.first+idx1[i],yy=t.second+idy1[i];
			if(check(xx,yy)&&v1[xx][yy]==0&&a[xx][yy]==1)
			{
				v1[xx][yy]=1;
				q.push({xx,yy});
			}	
		}
	   }
}//对遇见的岛屿及其连在一起的岛进行标记
void bfs2(int x,int y)
{
	queue<pair<int,int>> q;
	q.push({x,y});
	v2[x][y]=1;
	while(q.size())
	{
		auto t=q.front();
		q.pop();
		for(int i=0;i<8;i++)
		{
			int xx=t.first+idx2[i],yy=t.second+idy2[i];
			if(check(xx,yy)&&v2[xx][yy]==0&&a[xx][yy]==0)
			{
				v2[xx][yy]=1;
				q.push({xx,yy});
			}
				if(check(xx,yy)&&v1[xx][yy]==0&&a[xx][yy]==1)
				{
					ans++;
					bfs1(xx,yy);
				}
		}
	}
}//枚举外海
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>t;
	while(t--)
	{
    bool flag = false;
		ans=0;
		memset(v1,0,sizeof v1);
		memset(v2,0,sizeof v2);
		memset(a,0,sizeof a);
		cin>>n>>m;
		for(int i = 0; i < n; i ++)
	{
		string s; 
		cin >> s;
		for(int j = 0; j < m; j ++)
			a[i][j] = s[j] - '0';
	}
		for(int i=0;i<n;i++)
		for(int j=0;j<m;j++)
		{
			if(i==0||j==0){
			if(a[i][j]==0&&v2[i][j]==0){//外海肯定在最外面一圈
			bfs2(i,j);
      flag=true;
      }
		}
	}
  if(!flag) cout<<"1"<<endl;
  else
	     cout<<ans<<endl;	
	}
}

BFS宽度优先搜索)通常用于图论中的遍历算法,特别是在寻找连通分量、路径或最小生成树等问题时。在查找岛屿的数量时,你可以将其视为一个二维网格,其中'0'表示水域,'1'表示陆地。岛屿就是由相邻的陆地区域组成的,且四周边界也是陆地。 这里是一个简单的C++实现,使用BFS来计算字符串表示的二维数组中岛屿的数量: ```cpp #include <iostream> #include <queue> #include <string> int countIslands(const std::string& grid) { int m = grid.size(), n = grid[0].size(); int islands_count = 0; bool visited[m][n]; // 初始化为未访问 for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) visited[i][j] = false; // 定义队列并开始 BFS std::queue<std::pair<int, int>> q; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (grid[i][j] == '1' && !visited[i][j]) { islands_count++; q.push({i, j}); visited[i][j] = true; } } } while (!q.empty()) { int x = q.front().first, y = q.front().second; q.pop(); // 检查上下左右四个方向 if (x > 0 && grid[x - 1][y] == '1' && !visited[x - 1][y]) q.push({x - 1, y}), visited[x - 1][y] = true; if (x < m - 1 && grid[x + 1][y] == '1' && !visited[x + 1][y]) q.push({x + 1, y}), visited[x + 1][y] = true; if (y > 0 && grid[x][y - 1] == '1' && !visited[x][y - 1]) q.push({x, y - 1}), visited[x][y - 1] = true; if (y < n - 1 && grid[x][y + 1] == '1' && !visited[x][y + 1]) q.push({x, y + 1}), visited[x][y + 1] = true; } return islands_count; } int main() { std::string grid = "010010000010"; int islandCount = countIslands(grid); std::cout << "Number of islands: " << islandCount << std::endl; return 0; } ``` 在这个代码里,我们首先初始化一个`visited`数组记录每个位置是否已被访问过。然后,对每个格子进行检查,如果它是陆地且还未被访问,则标记为已访问,并增加岛屿计数。接着,我们用队列进行广度优先搜索,每次从队列中取出一个位置,然后在其周围四邻位置上重复此过程,直到所有可达的陆地都被处理过。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值