我正试图解决这个问题:
给出了一个矩形位图 大小n * m。位图的每个像素都是 白色或黑色,但至少 一个是白色的。第i行的像素 第j列称为像素 (I,J)。两个像素之间的距离 定义p1 =(i1,j1)和p2 =(i2,j2) 为:
d(p1,p2)=|i1-i2|+|j1-j2|.
任务
编写一个程序:
读取位图的描述 从标准输入,每个 像素,计算距离 最近的白色像素,写道 结果是标准输出。
输入
测试用例t的数量 第一行输入,然后是t测试用例 用空行分隔。在 每个测试用例的第一行 是一对整数n,m 由单个空格分隔,1 <= n &lt; = 182,1 <&lt; = m&lt; = 182。在每一个 以下n行测试用例 正好一个长度为零的零字, 一行的描述 位图,是写的。在第j个 行中的位置(i + 1),1&lt; = i&lt; = n,1&lt; = j&lt; = m,如果且仅当是,则为'1' 像素(i,j)是白色。
Output
在每个测试用例的第i行中, 1&lt; = i&lt; = n,应该写m 整数f(i,1),...,f(i,m)分开 单个空格,其中f(i,j)是 从像素(i,j)到的距离 最近的白色像素。
我提出的算法是:
这是我的实施:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
struct white{
int i;
int j;
};
int main()
{
int N;
cin >> N;
for (int z = 0; z < N; z++){
char bitmap[182][182];
int n,m;
cin >> n >> m;
vector<white> whites;
for (int i = 1; i <= n; i++){
string s;
cin >> s;
for (int j = 0; j < m; j++){
bitmap[i][j+1] = s[j];
if (s[j] == '1'){
white x;
x.i = i;
x.j = j+1;
whites.push_back(x);
}
}
}
int size = whites.size();
for (int i = 1; i <= n; i++){
for (int j = 1; j <= m; j++){
if (bitmap[i][j] == '0'){
int distance = 31223123;
for (int x = 0; x < size; x++){
int d = abs(i-whites[x].i) + abs(j-whites[x].j);
if (d < distance)
distance = d;
}
cout << distance << ' ';
} else {
cout << '0' << ' ';
}
}
cout << endl;
}
}
return 0;
}
尽管这样做有点太慢了。请帮我提高性能,或者这个算法可能不够快?
答案 0 :(得分:4)
您可以从另一端接近算法,而不是尝试计算从每个黑色位置到所有白色的距离,计算从白色元素到所有其他节点的距离。这将允许您削减许多计算:
这可以减少操作次数。您还可以尝试通过智能选择白点的顺序来启发式地提高性能。想象一下1D情况,如果您按唯一坐标对点进行排序,并使用以白色有序列表的中位数开头,则左侧的任何点都不需要检查超出该第一点的位置,以便您通过选择最佳分区其余空间的下一个白点,可以改善最坏的情况。
答案 1 :(得分:2)
这是图像处理的标准问题(“距离变换”)并且存在有效的算法,参考 例如http://en.wikipedia.org/wiki/Distance_transform
答案 2 :(得分:1)
关键是要考虑你已经给出的距离函数(L1 /出租车规范),以便进行最有效的搜索。
d(p1,p2)=|i1-i2|+|j1-j2|.
在给定像素周围,执行搜索的顺序应为
3
323
32123
3210123
3210x0123
3210123
32123
323
3
等
答案 3 :(得分:1)
我建议做类似David Rodriguez的解决方案:计算从白色像素开始的距离。但是,不是进行递归的深度优先搜索,而是使用队列代替广度优先。这可以保证您只需要遍历每个像素一次。
for each pixel (p):
cost(p) := +inf
queue := empty queue
for each white pixel (w):
cost(w) := 0
push(queue, w)
while queue is not empty:
p := pop(queue)
for each neighbour pixel (pn):
if cost(pn) == +inf:
cost(pn) = cost(p) + 1
push(queue, pn)