Description
假设我们有矩阵,其元素值非零即1
a11…… a1m
…………….
an1…….anm
定义aij与akl之间的距离为D(aij,akl)=abs(i-k)+abs(j-L)
Input
输入文件的第一行为两个整数,分别代表n和m。
接下来的n行,第i行的第 j个字符代表aij
Output
输出包含N行,每行M个用空格分开的数字,其中第i行第J个数字代表
Min(D(aij,axy) 1<=x<=N 1<=y<m,且axy=1
Sample Input
3 4
0001
0011
0110
0001
0011
0110
Sample Output
3 2 1 0
2 1 0 0
1 0 0 1
2 1 0 0
1 0 0 1
HINT
对于100%的数据,满足 0 < m n <=1000
Source
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;
}