输入一个只包含0和1的二维数组,上下左右和对角相邻的1组成一个区块,0不形成区块,求数组中的区块个数。
输入格式
第一行输入两个正整数N和M,N表示数组行数,M表示数组列数。
接下来N行,每行表示数组对应的一行,每行包含M个整数,整数之间用空格隔开。
输出格式
输出一个整数,表示数组中区块的个数。
数据范围
0≤N,M,N∗M≤1060≤N,M,N∗M≤106
输入样例:
3 3
0 1 0
1 0 0
1 0 1
输出样例:
2
样例解释
数组右下角的1单独构成一个区块,其他的3个1对角或上下相邻,构成另一个区块。
这道题目的输入有一点坑,不能直接开一个10^6 * 10^6 的二维数组,解决的办法是使用动态vector,记得初始化好,或者使用一个一维数组手动转换一下。
思路就是标准的染色方法,这里附件8块,直接用两重忙枚举即可
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
void dfs(vector<vector<int>> &nums, int i, int j)
{
nums[i][j] = 0;
for (int dx = -1; dx <= 1; dx++) {
for (int dy = -1; dy <= 1; dy++) {
int x = i + dx;
int y = j + dy;
if (x >= 0 && x < nums.size() && y >= 0 && y < nums[0].size() && nums[x][y])
dfs(nums, x, y);
}
}
}
int main()
{
int n, m, temp;
scanf("%d %d", &n, &m);
vector<vector<int>> nums(n, vector<int>(m, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &temp);
nums[i][j] = temp;
}
}
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (nums[i][j]) {
res++;
dfs(nums, i, j);
//cout << i << " " << j << endl;
}
}
}
/*for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
//scanf("%d", &temp);
//nums[i][j] = temp;
cout << nums[i][j] << " ";
}
cout << endl;
}*/
cout << res << endl;
}
当矩阵过大的时候, DFS可能会爆栈,有时需要自己写BFS
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
typedef pair<int, int> PII;
void bfs(vector<vector<int>> &nums, int sx, int sy)
{
queue<PII> q;
q.push({ sx,sy });
nums[sx][sy] = 0;
while (!q.empty()) {
auto t = q.front();
q.pop();
int x = t.first, y = t.second;
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
int a = x + i;
int b = y + j;
if (a >= 0 && a < nums.size() && b >= 0 && b < nums[0].size() && nums[a][b]) {
nums[a][b] = 0;
q.push({ a,b });
}
}
}
}
}
int main()
{
int n, m, temp;
scanf("%d %d", &n, &m);
vector<vector<int>> nums(n, vector<int>(m, 0));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &temp);
nums[i][j] = temp;
}
}
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (nums[i][j]) {
res++;
bfs(nums, i, j);
}
}
}
cout << res << endl;
}