描述
给定一个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]=min(1≤x≤N,1≤y≤M,A[x][y]=1)?{dist(A[i][j],A[x][y])}
即求与每个位置曼哈顿距离最近的1
N,M≤1000。
输入格式
第一行两个整数n,m。
接下来一个N行M列的01矩阵,数字之间没有空格。
输出格式
一个N行M列的矩阵B,相邻两个整数之间用一个空格隔开。
样例输入
3 4 0001 0011 0110
样例输出
3 2 1 0 2 1 0 0 1 0 0 1
题解:P108。将矩阵 A 中每一个 1 都看作起点,整个矩阵的所有位置都可以通行,对于每个位置,在从任何一个起点出发都可以的情况下,求到达该位置所需的最少步数。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#define ll long long
using namespace std;
const int maxn = 1000+7;
int n, m;
char a[maxn][maxn];
int b[maxn][maxn];
const int dx[4] = {-1,1,0,0}, dy[4] = {0,0,-1,1};
queue<pair<int, int> > q;
int main()
{cin >> n >> m;for(int i = 1; i <= n; i++)scanf("%s", a[i] + 1);memset(b, -1, sizeof b);for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++) {if(a[i][j] == '1')q.push(make_pair(i, j)), b[i][j] = 0;}}while(q.size()) {pair<int, int> now = q.front();q.pop();for(int i = 0; i < 4; i++) {pair<int, int> next(now.first+dx[i], now.second+dy[i]);if(next.first < 1 || next.second < 1 || next.first > n || next.second > m)continue;if(b[next.first][next.second] == -1){b[next.first][next.second] = b[now.first][now.second] + 1;q.push(next);}}}for(int i = 1; i <= n; i++) {for(int j = 1; j <= m; j++)printf("%d ", b[i][j]);puts("");}return 0;
}