给定一个N x M的01矩阵,其中1表示陆地,0表示水域。对于每一个位置,求出它距离最近的水域的距离是多少。
矩阵中每个位置与它上下左右相邻的格子距离为1。
第一行包含两个整数,N和M。
以下N行每行M个0或者1,代表地图。
数据保证至少有1块水域。
对于30%的数据,1 <= N, M <= 100
对于100%的数据,1 <= N, M <= 800
输出N行,每行M个空格分隔的整数。每个整数表示该位置距离最近的水域的距离。
4 4 0110 1111 1111 0110
0 1 1 0 1 2 2 1 1 2 2 1 0 1 1 0
思路:这题一看应该都知道是广搜题,跟有些题不一样的是,这题要先把值为0的点加入队列中,然后再一起广搜,如果想之前做题一样一个一个点搜一遍会超时。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#define inf 0x3fffffff
using namespace std;
typedef long long LL;
const int mod=1e9+7;
const int N=808;
char s[N][N];
bool vis[N][N];
int m,n,ans[N][N],dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
struct node
{
int x,y,step;
}now,net;
queue<node>q;
bool can(int x,int y)
{
if(x<0||x>=n||y<0||y>=m||vis[x][y]||s[x][y]=='0')
return false;
return true;
}
void bfs()
{
while(!q.empty())
{
now=q.front();
q.pop();
for(int i=0;i<4;i++)
{
net=now;
net.x+=dir[i][0];
net.y+=dir[i][1];
if(can(net.x,net.y))
{
net.step++;
vis[net.x][net.y]=true;
ans[net.x][net.y]=net.step;
q.push(net);
}
}
}
}
int main()
{
memset(vis,false,sizeof(vis));
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",s[i]);
for(int j=0;j<m;j++)
{
if(s[i][j]=='0')
{
ans[i][j]=0;
vis[i][j]=true;
now.x=i,now.y=j,now.step=0;
q.push(now);
}
}
}
bfs();
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
printf("%d ",ans[i][j]);
printf("\n");
}
}
本文介绍了一种使用广度优先搜索(BFS)算法来解决一个具体问题的方法:给定一个由0和1组成的矩阵,求解矩阵中每个位置到最近水域(标记为0的位置)的最短距离。通过将所有水域位置预先加入队列并进行广度优先搜索,有效地计算出了每个陆地位置(标记为1的位置)到最近水域的距离。
1084

被折叠的 条评论
为什么被折叠?



