像素距离泛滥

时间:2014-08-22 17:59:20

标签: c++ algorithm flood-fill

  

问题陈述

     

输入是一个矩形位图,如下所示:

0001
0011
0110
     

任务是找到每个黑色(0)“像素”,到达的距离   最接近的白色(1)“像素”。所以,上面的输出应该是:

3 2 1 0
2 1 0 0
1 0 0 1

我有一个解决问题的工作解决方案,我发布了here,询问有关性能改进的建议。为了实现@Jerry Coffin的解决方案(在问题的答案中建议),我编写了以下代码,不幸的是,它产生了垃圾输出。例如,问题陈述输入的输出是

1   1  1 0 
11  11 0 0 
110 0  0 1

为什么代码不起作用?

#include <iostream>
#include <string>
#include <queue>

using namespace std;

const unsigned short MAX = 200;

typedef unsigned short coordinate;
typedef pair<coordinate,coordinate> coordinates;

//Converts char[] to unsigned int
coordinate atou(char* s) {
    coordinate x = 0;
    while(*s) x = x*10 + *(s++) - '0';
    return x;
}

//Returns array of immediate neighbours of pixel of coordinates c
coordinates* neighbours_of(coordinates c) {
    static coordinates neighbours[7];
    coordinate i = c.first;
    coordinate j = c.second;
    neighbours[0] = coordinates(i+1,j);
    neighbours[1] = coordinates(i+1,j+1);
    neighbours[2] = coordinates(i,j+1);
    neighbours[3] = coordinates(i-1,j+1);
    neighbours[4] = coordinates(i-1,j);
    neighbours[5] = coordinates(i-1,j-1);
    neighbours[6] = coordinates(i,j-1);
    neighbours[7] = coordinates(i+1,j-1);
    return neighbours;
}

int main() {

    unsigned short test_cases, wave_number, initial_wave_size;
    coordinate m, n, i, j;
    int A[MAX][MAX];
    coordinates* directions;
    string row;
    queue<coordinates> ones;
    queue<coordinates> wave;
    coordinates current_coordinates;
    bool found_some_zero;
    cin >> test_cases;

    while(test_cases--) {

        //Input
        cin >> n;
        cin >> m;
        for(i = 0; i < n; i++) {
            cin >> row;
            for(j = 0; j < m; j++) {
                if(row[j] == '1') {
                    A[i][j] = -1;
                    ones.push(coordinates(i,j));
                } else A[i][j] = atou(&row[j]);
            }
        }

        //Initilization
        wave = ones;
        wave_number = 1;
        found_some_zero = true;

        //Filling algorithm
        while(found_some_zero) {
            found_some_zero = false;
            initial_wave_size = wave.size();
            while(initial_wave_size--) {
                current_coordinates = wave.front();
                directions = neighbours_of(current_coordinates);
                //Try all directions
                for(int k = 0; k < 8; k++) {
                    i = directions[k].first;
                    j = directions[k].second;
                    //If on screen and not yet visited
                    if(i < n && j < m && A[i][j] == 0) {
                        //Mark visited
                        A[i][j] = wave_number;
                        //(i,j) will be part the next wave
                        wave.push(coordinates(i,j));
                        found_some_zero = true;
                    }
                }
                wave.pop();
            }
            wave_number++;
        }

        //-1 to 0
        while(!ones.empty()) {
            current_coordinates = ones.front();
            i = current_coordinates.first;
            j = current_coordinates.second;
            A[i][j] = 0;
            ones.pop();
        }

        //Output
        for(i = 0; i < n; i++) {
            for(j = 0; j < m; j++)
                cout << A[i][j] << " ";
            cout << endl;
        }
    }
    return 0;
}

1 个答案:

答案 0 :(得分:1)

输入循环错误。而不是

            if(row[j] == '1') {
                A[i][j] = -1;
                ones.push(coordinates(i,j));
            } else A[i][j] = atou(&row[j]);

你需要做

            if(row[j] == '1') {
                A[i][j] = -1;
                ones.push(coordinates(i,j));
            } else A[i][j] = 0;

此外,neighbors[7]应为neighbors[8],如果您想要完全匹配指定的输出,则应仅使用四个基本方向。