思路:
看到这道题,大概率用BFS,考虑题目本题的情景,一开始因为不理解题目中的“两个像素被认为是“连通的”,如果它们有一个共同的切面”这句话,还在想为什么不能用二维,地图规模宽LM,长N
,方向的话上下左右对角线?不对啊,这样就4个 or 8个方向了,整不出6个方向啊?
不过看图示上下左右前后正好六个方向,而且题目输出也暗示了“输出肿瘤的总体积。”可以考虑三维,所以可以把地图规模看成长M,宽N,高L
。再者就是在最后比最普通的搜索多了判断当前块面积大小是否大于
t
t
t。
常规搜索步骤:
- 把未搜索过且位置为1的节点入队
- 相应的位置置为0表示已搜索
- 当前块面积c_sum加一
输入样例:
3 4 5 2
1 1 1 1
1 1 1 1
1 1 1 1
0 0 1 1
0 0 1 1
0 0 1 1
1 0 1 1
0 1 0 0
0 0 0 0
1 0 1 1
0 0 0 0
0 0 0 0
0 0 0 1
0 0 0 1
1 0 0 0
输出样例:
26
代码:
#include<bits/stdc++.h>
using namespace std;
int mp[65][1300][130];
int dir[6][3] = {{1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1}}; //6个方向
int m, n, l, t;
int sum; //总面积
typedef struct no{
int z, x, y;
}node;
int check(int k, int i, int j)
{
if (k<0 || k>=l || i<0 || i>=m || j<0 || j>=n) //越界判断
return 0;
return 1;
}
void bfs(int k, int i, int j)
{
queue<node> que;
node p, q;
p.z = k, p.x = i, p.y = j;
que.push(p);
mp[p.z][p.x][p.y] = 0;
int c_sum = 1;
while (!que.empty())
{
p = que.front();
que.pop();
for (int r = 0; r < 6; r++) // 遍历 6 个方向
{
q.z = p.z + dir[r][0];
q.x = p.x + dir[r][1];
q.y = p.y + dir[r][2];
if (check(q.z, q.x, q.y) && mp[q.z][q.x][q.y])
{
que.push(q);
mp[q.z][q.x][q.y] = 0;
c_sum++;
}
}
}
if (c_sum >= t) //只有连通块面积 >= t时才计入总面积
sum += c_sum;
}
int main()
{
cin >> m >> n >> l >> t;
for (int k = 0; k < l; k++)
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
cin >> mp[k][i][j];
for (int k = 0; k < l; k++)
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
if (mp[k][i][j])
bfs(k, i, j);
cout << sum <<endl;
return 0;
}