Problem Description 题目链接
现在我们给出一个n*m的黑白位图,n为行数,m为列数,且该位图中至少含有一个白色的像素。我们用(i,j)来表示第i行第j列的像素,并且定义两像素点p1=(i1,j1)和p2=(i2,j2)之间的距离为:d(p1,p2)=|i1-i2|+|j1-j2|。
对于任意给定的位图,计算出位图中每个像素到与它最近的白色像素之间的距离。
对于任意给定的位图,计算出位图中每个像素到与它最近的白色像素之间的距离。
Input
本题有多组输入数据,每组数据第一行包含两个整数n,m,用空格分开,1<=n,m<=182。之后的n行每行包含一个长度为m的由0和1组成的字符串,即第i行第j个字符如果为"1",那么表示像素(i,j)为白的,否则为黑的。
Output
对于每组数据,输出包含n行,第i行的第j个数字为f(i,j),表示像素(i,j)到最近的白色像素的距离。每行内的数字用空格分开。
Sample Input
3 4
0001
0011
0110
Sample Output
3 2 1 0
2 1 0 0
1 0 0 1
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <stdio.h> #include <queue> using namespace std; /* 思路:简单的BFS水题 可以用多源BFS一开始将1放入然后 然后一次次遍历即可 本来没必要记录但是有个坑以前没考虑到 请翻到最后 */ struct Pos { int x, y; }; int main() { int n, m; char map[185][185]; int visit[185][185]; int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; while (scanf("%d%d", &n, &m) != EOF) { queue<Pos> pq; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { cin >> map[i][j]; if (map[i][j] == '1') { visit[i][j] = 0; Pos t; t.x = i; t.y = j; pq.push(t); } else { visit[i][j] = -1; } } } //BFS即可 int step = 1; while (!pq.empty()) { int count = pq.size(); while (count--) { Pos p = pq.front(); pq.pop(); for (int i = 0; i < 4; i++) { int _x = dir[i][0] + p.x, _y = dir[i][1] + p.y; if (_x < 1 || _y < 1 || _x > n || _y > m || visit[_x][_y] != -1) continue; visit[_x][_y] = step; Pos t; t.x = _x; t.y = _y; pq.push(t); } } step++; } for (int i = 1; i <= n; i++) { printf("%d", visit[i][1]); for (int j = 2; j <= m; j++) { printf(" %d", visit[i][j]); } printf(" "); } } return 0; }
PS:以前有时候为了效率使用scanf()输入字符串,但是有时候多了回车使用getchar(),发现这样一来效率还不如使用cin,以下附上超时输入代码
queue<Pos> pq; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%c", &map[i][j]); if (map[i][j] == '1') { visit[i][j] = 0; Pos t; t.x = i; t.y = j; pq.push(t); } else { visit[i][j] = -1; } } getchar(); }