《算法竞赛进阶指南》矩阵距离

矩阵距离
给定一个 N 行 M 列的 01 矩阵 A,A[i][j] 与 A[k][l] 之间的曼哈顿距离定义为:

dist(A[i][j],A[k][l])=|i−k|+|j−l|
输出一个 N 行 M 列的整数矩阵 B,其中:

B[i][j]=min1≤x≤N,1≤y≤M,A[x][y]=1dist(A[i][j],A[x][y])
输入格式
第一行两个整数 N,M。

接下来一个 N 行 M 列的 01 矩阵,数字之间没有空格。

输出格式
一个 N 行 M 列的矩阵 B,相邻两个整数之间用一个空格隔开。

数据范围
1≤N,M≤1000
输入样例:
3 4
0001
0011
0110
输出样例:
3 2 1 0
2 1 0 0
1 0 0 1

#include
#include
#include
using namespace std;
typedef pair<int ,int > PII;
const int N=1010;
char g[N][N];
int d[N][N];//存储结果矩阵 
PII q[N*N];
int n,m;
void bfs()
{//本题是典型的bfs问题,由标记为‘1’的起始位置向四周扩展1个步数
//然后将新标记到的位置加入队列中,这样就能遍历步数从小到大
   memset(d,-1,sizeof d);//先将所有位置都标记为-1即没遍历过
   int hh=0,tt=-1;//hh为队尾,tt为队头 
   for(int i=1;i<=n;i++)
     for(int j=1;j<=m;j++)
	 if(g[i][j]=='1')
	 {
	      d[i][j]=0;
		  q[++tt]={i,j};//将初始得到的位置存如队列中	
	 }  
	 int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
	 //用于遍历向四个方向移动  
	while(hh<=tt)
	{
		auto t=q[hh++];
		int x=t.first,y=t.second;
		for(int i=0;i<4;i++)
		{
			int a=x+dx[i],b=y+dy[i];
			if(!a||a>n||!b||b>m||d[a][b]!=-1)continue;
			//当移动后的位置超出矩阵位置,或已经遍历过时,向其他方向进行移动 
            d[a][b]=d[x][y]+1;//步数加1 
			q[++tt]={a,b};//经新的移动位置加入队列中 
		}
	}
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	cin>>(g[i]+1);
	bfs();
    for(int i=1;i<=n;i++)
       {
       	for(int j=1;j<=m;j++)
       	cout<<d[i][j]<<' ';
       	cout<<endl;
	   }
	   return 0;
}

你可能感兴趣的:(bfs搜索)