求矩阵连通域的个数

    实际上是个宝石迷阵消除游戏的简化版,把不同颜色的宝石看成不同值的数字,然后连通超过三个的可以消除。这里没有加入消除后降落的机制,一定程度上简化了问题的复杂度。那种需要每次消除后都从头遍历……

#include <iostream>
 
using namespace std;
 
template<typename T>
T &val(T *matrix, int w, int h, int i, int j)
{
    return *(matrix + j * w + i);
}
 
int unguarded_count_area_size(int *matrix, bool *visit, int w, int h, int i, int j, int value)
{
    if (i < 0 || i >= w) return 0;
    if (j < 0 || j >= h) return 0;
 
    if (val(visit, w, h, i, j) == true || val(matrix, w, h, i, j) != value)
    {
        return 0;
    }
 
    val(visit, w, h, i, j) = true;
 
    const int left = unguarded_count_area_size(matrix, visit, w, h, i - 1, j, value);
    const int right = unguarded_count_area_size(matrix, visit, w, h, i + 1, j, value);
    const int top = unguarded_count_area_size(matrix, visit, w, h, i, j - 1, value);
    const int bottom = unguarded_count_area_size(matrix, visit, w, h, i, j + 1, value);
 
    return left + right + top + bottom + 1;
}
 
int count_area(int *matrix, int w, int h)
{
    if (matrix == NULL || w <= 0 || h <= 0)
    {
        return 0;
    }
 
    bool *visit = new bool[w * h];
    int sum = 0;
 
    memset(visit, 0, sizeof(bool) * w * h);
 
    for (int j = 0; j < h; ++j)
    {
        for (int i = 0; i < w; ++i)
        {
            const int size = 
                unguarded_count_area_size(matrix, visit, w, h, i, j, val(matrix, w, h, i, j));
 
            if (size >= 3) ++sum;
        }
    }
 
    delete[] visit;
    return sum;
}
 
 
int main(int argc, char **argv)
{
    int data[][8] = 
    {
        1, 1, 2, 1, 3, 4, 5, 4,
        1, 2, 2, 1, 3, 4, 4, 4,
        1, 1, 1, 1, 3, 5, 5, 5
    };
 
    cout << count_area((int *)data, 8, 3) << endl;
    return 0;
}
posted @ 2012-09-04 23:20  紫红的泪  阅读(4022)  评论(0编辑  收藏  举报