P8662 [蓝桥杯 2018 省 AB] 全球变暖 题解
1. 编程思路。
对给定海域中的每个陆地像素,从它出发用 BFS 搜索包括这个陆地像素的连通块,置连通块中的每个路地像素
用 BFS 找出每个连通块,所有连通块中
2. 源程序。
#include <stdio.h>
#include <string.h>
#define N 1005
char a[N][N];
int n,vis[N][N],dir[4][2]={{-1,0},{0,-1},{0,1},{1,0}};
struct Point
{
int x,y;
};
struct Point q[1000000];
int bfs(int x,int y)
{
struct Point p;
p.x=x; p.y=y;
int front=0,rear=0;
q[rear++]=p;
int left=0; // 表示一个连通块中留下的没有被淹没的陆地像素
while (front<rear)
{
p=q[front++];
int i,cnt=0;
for (i=0;i<4;i++)
{
int dx=p.x+dir[i][0];
int dy=p.y+dir[i][1];
if (dx<0 || dx>=n || dy<0 || dy>=n)
continue;
if (a[dx][dy]=='#')
{
cnt++;
if (!vis[dx][dy])
{
vis[dx][dy]=1;
q[rear].x=dx;
q[rear].y=dy;
rear++;
}
}
}
if (cnt==4) // 如果一个陆地像素的上下左右四个方向也是陆地像素
left++; // 这个陆地像素肯定不会被淹没,留下了
}
return left;
}
int main()
{
int i,j,ans=0;
scanf("%d",&n);
for (i=0;i<n;i++)
{
scanf("%s",a[i]);
}
memset(vis,0,sizeof(vis));
for (i=0;i<n;i++)
{
for (j=0;j<n;j++)
{
if (a[i][j]=='#'&& !vis[i][j]) // 从这个没有访问过的陆地像素出发寻找其连通块
{
vis[i][j]=1;
if (!bfs(i,j)) // 包含(i,j)陆地像素的连通块中的陆地像素全部被淹没,left=0
ans++; // 被淹没的岛屿个数加 1
}
}
}
printf("%d\n",ans);
return 0;
}