AcWing 4959 岛屿个数

题目涉及在一个M×N的格子地图中,通过Bfs算法寻找由相连陆地形成的岛屿,并计算独立岛屿总数。
摘要由CSDN通过智能技术生成

题目
小蓝得到了一副大小为 M×N的格子地图,可以将其视作一个只包含字符 0(代表海水)和 1(代表陆地)的二维数组,地图之外可以视作全部是海水,每个岛屿由在上/下/左/右四个方向上相邻的 1 相连接而形成。

在岛屿 A所占据的格子中,如果可以从中选出 k 个不同的格子,使得他们的坐标能够组成一个这样的排列:(x0,y0),(x1,y1),…,(xk−1,yk−1),其中 (x(i+1)%k,y(i+1)%k) 是由 (xi,yi) 通过上/下/左/右移动一次得来的 (0≤i≤k−1),此时这 k个格子就构成了一个 “环”。

如果另一个岛屿 B
所占据的格子全部位于这个 “环” 内部,此时我们将岛屿 B 视作是岛屿 A的子岛屿。

若 B是 A 的子岛屿,C 又是 B 的子岛屿,那 C 也是 A的子岛屿。

请问这个地图上共有多少个岛屿?

在进行统计时不需要统计子岛屿的数目。

输入格式

第一行一个整数 T,表示有 T组测试数据。接下来输入 T组数据。
对于每组数据,第一行包含两个用空格分隔的整数 M、N
表示地图大小;接下来输入 M 行,每行包含 N个字符,字符只可能是 0 或 1。

输出格式

对于每组数据,输出一行,包含一个整数表示答案。

数据范围

对于 30%的评测用例,1≤M,N≤10。
对于 100% 的评测用例,1≤T≤10,1≤M,N≤50。
输入样例:

2
5 5
01111
11001
10101
10001
11111
5 6
111111
100001
010101
100001
111111

输出样例:

1
3
#include<bits/stdc++.h>
using namespace std;
int sx[8] = {1,1,1,0,0,-1,-1,-1}, sy[8] = {1,0,-1,1,-1,1,0,-1};
int landx[4] = { 1,0,0,-1 }, landy[4] = {0,1,-1,0};
typedef pair<int, int> PII;
const int N = 55;
int graph[N][N];
bool judge[N][N];
int n, m,T;
int res = 0;
void Bfs_land(int x, int y)
{
	queue<PII> Q;
	Q.push({ x,y });
	judge[x][y] = true;
	//搜索四个方向的区块,只搜索陆地区块加入队列,海水则不在搜索范围内,一次搜索找出一个岛屿
	while (!Q.empty())
	{
		PII now = Q.front();
		Q.pop();
		for (int i = 0; i < 4; i++)
		{
			int nx = now.first + landx[i], ny = now.second + landy[i];
			if (nx >= 0 && nx <= n && ny >= 0 && ny <= m)
			{
				if (!judge[nx][ny] && graph[nx][ny] == 1)
				{
					Q.push({ nx,ny });
					judge[nx][ny] = true;
				}
			}
		}

	}
	return;
}
void Bfs_Sea(int x,int y)
{
	queue<PII> Q;
	Q.push({ x,y });
	judge[x][y] = true;
	//搜索八个方向的区块,是陆地则跳入Bfs_land搜索陆地,搜索完毕后,即找到一个岛屿; 如果是海水,则加入队列继续搜索
	while(!Q.empty())
	{
		PII now = Q.front();
		Q.pop();
		for (int i = 0; i < 8; i++)
		{
          int nx = now.first + sx[i], ny = now.second + sy[i];
		  if (nx >= 0 && nx <= n + 1 && ny >= 0 && ny <= m + 1)
		  {
			  if (!judge[nx][ny])
			  {
				  if (graph[nx][ny] == 1)
				  {
					  res++;
					  Bfs_land(nx,ny);
				  }
				  else
				  {
					  Q.push({ nx,ny });
					  judge[nx][ny] = true;
				  }
			  }
		  }
		}
		
	}
	return;
}
int main()
{
	cin >> T;
	while (T--)
	{
		memset(judge, false, sizeof judge);
		memset(graph, 0, sizeof graph);
		res = 0;
        cin >> n >> m;
	    for (int i = 1; i <= n; i++)
	    {
		    for (int j = 1; j <= m; j++)
		    {
			   char c;
			   cin >> c;
			   graph[i][j] = c - '0';
		    }
	    }
		
	    Bfs_Sea(0, 0);
	    cout << res << endl;
	}
	return 0;
}

原题地址

思路来源 --ACwing题解 by 煜.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值