#include <bits/stdc++.h>
#define INF 0x3f
using namespace std;
const int maxn = 1010;
char s[maxn][maxn];
int dp[4][maxn][maxn];
int n , m;
signed main()
{
scanf("%d %d" , &n , &m);
for(int i = 1; i <= n; i ++){
scanf("%s" , s[i] + 1);
}
memset(dp , 0x3f , sizeof dp);
for(int i = 1; i <= n; i ++){ //初始化
for(int j = 1; j <= m; j ++){
if(s[i][j] == '1'){ //白色点到自己的距离为0
for(int k = 0; k < 4; k ++){
dp[k][i][j] = 0;
}
}
}
}
for(int i = 1; i <= n; i ++){ //搜索上方和左方
for(int j = 1; j <= m; j ++){
if(dp[0][i][j] == 0){ //是白色点就跳过
continue;
}
dp[0][i][j] = min(dp[0][i - 1][j] , dp[0][i][j - 1]);
if(dp[0][i][j] != INF){ //附近有白色点可达的路径
dp[0][i][j] ++; //加一
}
}
}
for(int i = 1; i <= n; i ++){ //搜索上面和右面
for(int j = m; j >= 1; j --){
if(dp[1][i][j] == 0){ //是白色点就跳过
continue;
}
dp[1][i][j] = min(dp[1][i - 1][j] , dp[1][i][j + 1]);
if(dp[1][i][j] != INF){ //附近有白色点可达的路径
dp[1][i][j] ++; //加一
}
}
}
for(int i = n; i >= 1; i --){ //搜索下面和左面
for(int j = 1; j <= m; j ++){
if(dp[2][i][j] == 0){ //是白色点就跳过
continue;
}
dp[2][i][j] = min(dp[2][i + 1][j] , dp[2][i][j - 1]);
if(dp[2][i][j] != INF){ //附近有白色点可达的路径
dp[2][i][j] ++; //加一
}
}
}
for(int i = n; i >= 1; i --){ //搜索下面和右面
for(int j = m; j >= 1; j --){
if(dp[3][i][j] == 0){ //是白色点就跳过
continue;
}
dp[3][i][j] = min(dp[3][i + 1][j] , dp[3][i][j + 1]);
if(dp[3][i][j] != INF){ //附近有白色点可达的路径
dp[3][i][j] ++; //加一
}
}
}
/*
for(int k = 0; k < 4; k ++){
cout << k << ":\n";
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j ++){
printf("%-12d" , dp[k][i][j]);
}
cout << endl;
}
cout << endl;
}
*/
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j ++){
printf("%d " , min({ dp[0][i][j] , dp[1][i][j] , dp[2][i][j] , dp[3][i][j] }) );
}
printf("\n");
}
return 0;
}
借鉴了题解中的一些思路