字节跳动2019笔试:二维数组区块计数(超详细的解法!!!)

输入一个只包含0和1的二维数组,上下左右和对角相邻的1组成一个区块,0不形成区块,求数组中的区块个数。

输入格式

第一行输入两个正整数N和M,N表示数组行数,M表示数组列数。

接下来N行,每行表示数组对应的一行,每行包含M个整数,整数之间用空格隔开。

输出格式

输出一个整数,表示数组中区块的个数。

数据范围

0 ≤ N , M , N ∗ M ≤ 1 0 6 0≤N,M,N∗M≤10^6 0N,M,NM106

输入样例

3 3
0 1 0
1 0 0
1 0 1

输出样例

2

样例解释

数组右下角的1单独构成一个区块,其他的3个1对角或上下相邻,构成另一个区块。

解题思路

简单的dfs问题,和Leetcode 200:岛屿的个数(最详细的解法!!!)类似,只是我们这里的方向多了斜角方向。

我们通过遍历矩阵每个元素,如果访问到的元素是1的话,我们首先记录结果+1,表示我们遍历到了一个数组区块。然后我们将这个元素变为0,继续dfs下去。

#include 
using namespace std;
const int N = 1e6 + 10;
int mat[N];

int res, n, m;;
int dire[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
void dfs(int k)
{
    for (int i = 0; i < 8; ++i)
    {
        int x = dire[i][0] + k/m, y = dire[i][1] + k%m;
        int p = x * m + y;
        if (x >= 0 && x < n && y >= 0 && y < m && mat[p] == 1)
            mat[p] = 0, dfs(x*m + y);
    }
}

int main()
{
    cin >> n >> m;
    for (int i = n*m-1; i >= 0; --i) cin >> mat[i];
    for (int i = n*m-1; i >= 0; --i)
    {
        if (mat[i] == 1)
        {
            ++res, mat[i] = 0;
            dfs(i);
        }
    }
    cout << res << endl;
}

如有问题,希望大家指出!!!

你可能感兴趣的:(Problems)