FZU1408 位图

 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();
        }        
原文地址:https://www.cnblogs.com/dlvguo/p/12759698.html