Description
给定一个由 0 和 1 组成的矩阵,找出每个元素到最近的 0 的距离。
两个相邻元素间的距离为 1 。
Input
第一行两个整数n m ( 1 ≤ n,m ≤ 100 )
接下来输入 n行 m列 的二维数组。
3 3
0 0 0
0 1 0
0 0 0
Output
输出每个元素到最近的 0 的距离。
0 0 0
0 1 0
0 0 0
Sample Input
3 3
0 0 0
0 1 0
1 1 1
Sample Output
0 0 0
0 1 0
1 2 1
#include<iostream>
#include<map>
#include<queue>
using namespace std;
struct N{
int x;
int y;
int temp;
}num[101][101],sum; //使用结构体存储一个点的所有信息在这里也存储它的横纵坐标
//是因为当在循环到某一时刻时是不能判断改点的横纵坐标的
int n,m;
int main(){
cin>>n>>m;
queue<N>que; //建立该结构体类型的队列
int k;
for(int i=0;i<n;i++) //将坐标及该点初始到最近0点的距离
for(int j=0;j<m;j++){ //每个点的temp数据存储0或1带表它们的起始数据
cin>>num[i][j].temp;
num[i][j].x=i;
num[i][j].y=j;
if(num[i][j].temp==0){
que.push(num[i][j]); //因为该题要用到bfs搜索 又因为是计算到最近0的距离
//所以应该从0开始搜索
}
else{
num[i][j].temp=99999; //当该点不是0时即该点到最近0的距离未知
//又因为是求最近点所以初始值存储为99999的类似无限大的值
}
}
while(!que.empty()){
//由队列中的结构体一步一步的向外扩展
sum=que.front();
int x1=sum.x,y1=sum.y,temp1=sum.temp; //取出该点的坐标和它到最近0点的距离
//以下是由该点扩展的bfs搜索
if(x1>0){ //向上走
if(num[x1-1][y1].temp>temp1+1){ //当能向上搜索时如果向上的那个数据到最近0的距离大于
//由该点扩展到它的位置得到的最近0点的距离
//那么将向上一个点的到最近0的距离进行“刷新”
//并且向上的那个点要加入到队列中因为还要进行bfs搜索
num[x1-1][y1].temp=temp1+1;
que.push(num[x1-1][y1]);
}
//下面的向另外3个方向的搜索与该方向的搜索的原理是相同的
}
if(y1<m-1){ //向右走
if(num[x1][y1+1].temp>temp1+1){
num[x1][y1+1].temp=temp1+1;
que.push(num[x1][y1+1]);
}
}
if(x1<n-1){ //向下走
if(num[x1+1][y1].temp>temp1+1){
num[x1+1][y1].temp=temp1+1;
que.push(num[x1+1][y1]);
}
}
if(y1>0){
if(num[x1][y1-1].temp>temp1+1){
num[x1][y1-1].temp=temp1+1;
que.push(num[x1][y1-1]);
}
}
que.pop();//每次搜索外该数据就将它出队进行下一个数据的bfs搜索
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cout<<num[i][j].temp<<" ";
}
cout<<endl;
}
}
//我对while(1)循环中的bfs搜索是这样理解的 从第一类循环开始
//因为都是对0的bfs搜索并进行“数据刷新”后 在次存入队列中的就是到0的最近的距离为1的数据
//那么第二类循环就是对到0距离为1的数据进行bfs搜索将 到0的最近的距离为2的数据存入队列
//以此类推 每一类循环就相当于由0向外扩展一层直到不能扩展位置也就是队列为空时