题目描述
给定一个n x m
的矩阵A
,矩阵中的元素为0或1。定义A[i][j]
和A[x][y]
之间的曼哈顿距离为dist(A[i][j], A[x][y]) = |i - x| + |j - y|
。需要计算并输出一个同样大小的矩阵B
,其中B[i][j]
表示A[i][j]
到最近的1的曼哈顿距离。如果A[i][j]
本身是1,则B[i][j]
为0。
输入格式
- 第一行包含两个整数
n
和m
,表示矩阵的行数和列数。 - 接下来的
n
行,每行包含m
个整数(只包含0或1),表示矩阵A
的内容。
输出格式
输出一个n x m
的矩阵B
,表示每个位置到最近的1的曼哈顿距离。
示例
输入示例 1
3 4
0001
0011
0110
输出示例1
3 2 1 0
2 1 0 0
1 0 0 1
数据范围与约定
1<=n,m<=1000
代码示例
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 7, M = N * N;
// 四个方向 --- 方向向量
int dir[4][2] = {{-1, 0}, {0, 1}, {0, -1}, {1, 0}};
// bfs没一点都是坐标
struct node {
int x, y;
};
// 地图数组
char g[N][N];
// 距离数组
int dist[N][N];
int n, m;
// 多源bfs
void bfs() {
memset(dist, -1, sizeof(dist));
queue<node> q;
// 把所有起点放进去 --- 1当作起点
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (g[i][j] == '1') {
dist[i][j] = 0;
q.push({i, j});
}
}
}
// 正常写bfs
while (!q.empty()) {
node t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int xx = t.x + dir[i][0], yy = t.y + dir[i][1];
// 合法性检验 --- 看看越界了吗
if (xx < 0 || xx >= n || yy < 0 || yy >= m) continue;
// 合理性检验 --- 看看之前是否已经确定过了 --- bfs第一次就是最小
if (dist[xx][yy] != -1) continue;
// 这里就是说明可以执行逻辑了
dist[xx][yy] = dist[t.x][t.y] + 1;
q.push({xx, yy});
}
}
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> g[i];
bfs();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << dist[i][j] << " \n"[j == m - 1];
}
}
// string str = " \n";
// str[0] == ' ', str[1] = '\n';
// [j == m - 1]这个是不是就是下标
// j != m - 1 -> false -> 0 -> str[0];
// j == m - 1 -> true -> 1 -> str[1];
return 0;
}