假设我们有矩阵,其元素值非零即1
a11…… a1m
…………….
an1…….anm
定义aij与akl之间的距离为D(aij,akl)=abs(i-k)+abs(j-L)
输入文件的第一行为两个整数,分别代表n和m。
接下来的n行,第i行的第 j个字符代表aij
输出包含N行,每行M个用空格分开的数字,其中第i行第J个数字代表
Min(D(aij,axy) 1<=x<=N 1<=y<m,且axy=1
对于100%的数据,满足 0 < m n <=1000
BFS,为了简便可以逆向思维,从是1的点反过来搜,可以不用queue,用两个数组x[]、y[]模拟队列就行,再者要注意判重合,还要重视是1的点的dis数组初始化为0,被坑了,艹。。
#include <stdio.h> #include <string.h> #define MAXN 1050 int xx[4]={1,-1,0,0},yy[4]={0,0,1,-1}; //四个方向你懂的 int dis[MAXN][MAXN],map[MAXN][MAXN],n,m,cnt=1,x[1000*MAXN],y[1000*MAXN]; //dis[i][j]=Min(D(aij,axy),cnt=1的个数,x[i]=第i个1的x坐标,y同理 char in[MAXN]; void bfs() //由是1的点为起点bfs,下面的思路类似于队列 { int t=0; while(t<cnt) { int i=x[t],j=y[t],k; //获得队首点坐标 for(k=0;k<4;k++) //四个方向走 { int nowx=i+xx[k],nowy=j+yy[k]; if(nowx<1||nowx>n||nowy<1||nowy>m||dis[nowx][nowy]!=-1) continue; //移动后越界了或是已经搜索过,跳过 dis[nowx][nowy]=dis[i][j]+1; //移动了一步,更新距离=dis(i,j)+1 x[cnt]=nowx; //移动后的点入队 y[cnt]=nowy; cnt++; } t++; //队首的点四个方向走完后出队 } } int main() { int i,j; memset(dis,-1,sizeof(dis)); scanf("%d%d",&n,&m); for(i=1;i<=n;i++) { scanf("%s",in); for(j=1;j<=m;j++) if(in[j-1]=='1') { dis[i][j]=0; //注意初始化!!!妈的。。。 x[cnt]=i; y[cnt]=j; cnt++; } } bfs(); for(i=1;i<=n;i++) { for(j=1;j<=m;j++) printf("%d ",dis[i][j]); printf("\n"); } return 0; }