本题考BFS应用,题目大意是给出一个三维0,1矩阵,你需要对任意一个元素的上下左右前后进行判断枚举,如果当前元素为1且满足要求,则入队,当前枚举结束后如果该’1’矩阵不小于一个’l’代表的阈值则返回其中’1’的数量,其实原题要求我们对每一个满足要求的’1’矩阵求其体积volum,但是因为每一个1代表一个符合要求的元素,所以直接对1的个数进行计数就可以省去求体积的繁琐步骤,对于这种需要枚举矩阵中不同方向的元素的题目,通常选择使用一个“增量数组”来解决,初始化每个方向的所有可能值进入数组中就可以对任意一个位置的元素实现不同方向的遍历。BFS与DFS一样,有一个类似于模板的思路,我已经总结发布在“算法”目录里,有意者可以从我的主页中查找得到。
代码:
#include<cstdio>
#include<queue>
using namespace std;
struct node{
int x,y,z;
}Node;
int m,n,slice,t;
int pixel[1290][130][61];
bool inq[1290][130][61] = {false};
int X[6] = {0,0,0,0,1,-1};
int Y[6] = {0,0,1,-1,0,0};
int Z[6] = {1,-1,0,0,0,0};
bool judge(int x,int y,int z){
if(x < 0 || x>= n || y < 0 || y >= m || z < 0 || z >= slice) return false;
if(inq[x][y][z] == true || pixel[x][y][z] == 0) return false;
return true;
}
int bfs(int x,int y,int z){
int tot = 0;
queue<node> q;
Node.x = x; Node.y = y; Node.z = z;
q.push(Node);
inq[x][y][z] = true;
while(!q.empty()){
node top = q.front();
q.pop();
tot++;
for(int i=0;i<6;i++){
int newx = top.x + X[i];
int newy = top.y + Y[i];
int newz = top.z + Z[i];
if(judge(newx,newy,newz)){
q.push({newx,newy,newz});
inq[newx][newy][newz] = true;
}
}
}
if(tot >= t) return tot;
else return 0;
}
int main() {
scanf("%d%d%d%d", &n, &m, &slice, &t);
for (int z = 0; z < slice; z++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
scanf("%d", &pixel[i][j][z]);
}
}
}
int ans = 0;
for (int z = 0; z < slice; z++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (pixel[i][j][z] == 1 && inq[i][j][z] == false) {
ans += bfs(i, j, z);
}
}
}
}
printf("%d\n", ans);
return 0;
}