件名アドレス:
https://www.acwing.com/problem/content/175/
与えられたNNNラインMM列Mの0− 1 0-10−1マトリックスAAA、A [i] [j] A [i] [j]A [ i ] [ j ]およびA [k] [l] A [k] [l]A [ k ] [ l ]間のマンハッタン距離は次のように定義されます: d(A [i] [j]、A [k] [l])= ∣ i − k ∣ + ∣ j − l ∣ d(A [i ] [j]、A [k] [l])= | i−k | + | j−l |d (A [ i ] [ j ] 、A [ k ] [ l ] )=∣ i − k ∣+| J - L |
出力NNNラインMMM列整数行列BBB、中: B [i] [j] = min1≤x≤N、1≤y≤M、A [x] [y] = 1 d(A [i] [j]、A [x] [ y])B [i] [j] = \ min_ {1≤x≤N、1≤y≤M、A [x] [y] = 1} d(A [i] [j]、A [x] [y])B [ i ] [ j ]=1 ≤ X ≤ N 、1 ≤ Y ≤ M 、A [ X ] [ Y ] = 1私d (A [ i ] [ j ] 、A [ x ] [ y ] )
入力形式:
最初の行に2つの整数N、MN、MN 、M。次のNNNラインMM列Mの0− 1 0-10−1行列、数値間にスペースはありません。
出力フォーマット:NN
NラインMMM-カラムマトリックスBBB、2つの隣接する整数の間のスペースで区切られます。
データ範囲:
1≤N、M≤10001≤N、M≤10001≤N 、M≤1 0 0 0
問題は、各位置の最も近い11を見つけることです1のマンハッタン距離。アイデアはBFSです。あなたは仮想の出発点を想像することができます、この点はマトリックスのすべての11に行くことができます1で、エッジの重みは00です。0は、この仮想開始点からすべての位置までの最短距離を尋ねるのと同じで、BFSを使用できます。コードは次のように表示されます。
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1010, d[] = {
1, 0, -1, 0, 1};
int n, m;
char a[N][N];
int dist[N][N];
void bfs() {
memset(dist, -1, sizeof dist);
queue<pair<int, int>> q;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (a[i][j] == '1') {
q.push({
i, j});
dist[i][j] = 0;
}
while (!q.empty()) {
auto t = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
int nx = t.first + d[i], ny = t.second + d[i + 1];
// dist第一次算出来的时候代表的就是最短距离,所以对于已经算过的点不需要再次入队,只需把还没算出的点算一下最短距离并入队
if (1 <= nx && nx <= n && 1 <= ny && ny <= m && a[nx][ny] == '0' && dist[nx][ny] == -1) {
dist[nx][ny] = dist[t.first][t.second] + 1;
q.push({
nx, ny});
}
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
bfs();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
cout << dist[i][j] << ' ';
cout << endl;
}
return 0;
}
時間と空間の複雑さO(NM)O(NM)O (N M )。