给定一个 nm 的矩形位图,位图中的每个像素不是白色就是黑
色,但至少有一个是白色的。第 i 行第 j 列的像素被称作像素(i, j)。两个像
素 p1=(i1, j1),p2=(i2, j2) 之间的距离定义为:d (p1, p2) = |i1-i2| + |j1 - j2|。现在
请设计一个时间复杂度尽可能低的算法来计算图中每个像素与离其最近
的“白像素”的距离。
输入:第 1 行包含两个整数 n 和 m (1≤n≤150, 1≤m≤150),用一个空格隔开。
接下来 n 行,每一行都包含一个长度为 m 的 01串。第 i+1 行第 j
列的字符若为 1,则像素(i, j)是白色的;否则是黑色的。
输出:包含 n 行,每行有 m 个用空格隔开的整数。第 i 行第 j 列的整数表
示(i, j)与离其最近的白像素之间的距离。
要求:
(1) 描述算法的基本设计思想;
(2) 根据设计思想,采用类 C 语言的伪代码描述算法,关键之处给出注释。
(3) 说明你所设计的算法的时间复杂度
#include <iostream>
#include <queue>
#include <climits>
using namespace std;
//定义
struct Point {
int x;
int y;
};
// 定义方向数组,表示上下左右四个方向的偏移
int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};
// 定义一个函数,计算每个像素与离其最近的白像素之间的距离
void calculateDistances(int n, int m, char bitmap[][150]) {
// 创建一个二维数组用于存储每个像素点的距离
int distances[150][150];
// 初始化距离数组,将所有像素的距离初始化为无穷大
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
distances[i][j] = INT_MAX;
}
}
// 创建一个队列用于BFS
queue<Point> q;
// 将所有白像素加入队列,并初始化它们的距离为0
for (int i = 0; i < n-1; ++i) {
for (int j = 0; j < m; ++j) {
if (bitmap[i+1][j] == '1') {//i+1行j列为1 则i行j列为白元素 所以最后一行不用遍历
q.push({i, j});
distances[i][j] = 0;
}
}
}
// 进行BFS遍历
while (!q.empty()) {
Point current = q.front();//返回首元素
q.pop();//删除首元素
// 遍历当前像素的四个方向
for (int d = 0; d < 4; ++d) {
int nx = current.x + dx[d];
int ny = current.y + dy[d];
// 判断新坐标是否越界,并且距离是否更新
if (nx >= 0 && nx < n && ny >= 0 && ny < m &&
distances[nx][ny] == INT_MAX) {
distances[nx][ny] = distances[current.x][current.y] + 1;
q.push({nx, ny});
}
}
}
// 输出距离数组
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
cout << distances[i][j] << " ";
}
cout << endl;
}
}
// 主函数
int main() {
int n, m;
cin >> n >> m;
// 读取位图数据
char bitmap[150][150];
for (int i = 0; i < n; ++i) {
cin >> bitmap[i];
}
// 调用计算距离的函数
calculateDistances(n, m, bitmap);
return 0;
}
首先,我们可以使用广度优先搜索(BFS)算法来计算每个像素点到离其最近的白像素的距离。我们从所有白像素出发,以它们为起点进行BFS遍历,将每个被遍历到的黑像素标记上距离。这样,最终每个像素点的距离就被计算出来了。