脑子由薄片组成,MxN是一片薄片的长与宽,L是片数,T是单个中风核心的体积的阈值。
若三维矩阵中有若干个邻接的像素1,则这些像素1构成了1块中风核心。
可能出现多个中风核心区域,必须满足条件:单个体积>=T,求中风核心的总体积之和。
注意:
- 矩阵数据的输入是按层按行按列的
- 三维数组matrix记录输入的0、1数据;三维数组v记录对应像素是否被访问;
- 遍历每一个像素1,查看其是否被访问,查看和它邻接的6个像素是否为1且是否被访问过,继续查看与邻接像素们邻接的像素是否被访问过。。直到找不到与他们邻接的像素,确定了一个“块”。
- 继续遍历每一个像素1,重复以上步骤,直到遍历完所有像素1,得出总块数。
- judge函数判断该像素是否需要访问:是否出界(边界像素的邻接像素不到6个),像素是否为1,是否已被访问。
- 确定一个“块”时运用队列:
- 遍历每一个像素1,查看其是否被访问,若没有则进入队列;
- 取队头元素,查看和它邻接的6个像素是否为1且是否被访问过,没有则进入队列并设置为被访问。
- 重复步骤2,直到队列为空。(这一步做的是:查找该点和邻接像素、邻接像素的邻接像素等,尽可能扩大搜索像素1的范围)
- 设置三个增量数组,方便查找6个邻接像素
注意:队列中的元素只是复制的副本,某个元素入队后更改该元素的值,不会影响队列内该元素原本的值。
#include<cstdio>
#include<queue>
using namespace std;
struct node{
int x,y,z;
}Node;
int n,m,slice,T;
int pixel[1290][130][61];//三维0-1序列
bool isq[1290][130][61];//是否入队过
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>=n||x<0||y>=m||y<0||z>=slice||z<0) return false;
//为0或已经入队
if(pixel[x][y][z]==0||isq[x][y][z]==true) return false;
//以上都不满足返回true
return true;
}
//BFS,用前需要用judge判断
int BFS(int x,int y,int z){
int tot = 0;//块中1的个数
queue<node> Q;
Node.x = x;
Node.y = y;
Node.z = z;
Q.push(Node);//入队
isq[x][y][z] = true;
while(Q.empty()==false){//队列未空
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)){
Node.x = newX;
Node.y = newY;
Node.z = newZ;
Q.push(Node);
isq[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 x = 0;x<n;x++){
for(int y = 0;y<m;y++ ){
scanf("%d",&pixel[x][y][z]);
}
}
}
int ans = 0;
for(int z = 0;z<slice;z++){//切片
for(int x = 0;x<n;x++){
for(int y = 0;y<m;y++ ){
if(pixel[x][y][z]==1&&isq[x][y][z]==false) ans += BFS(x,y,z);
}
}
}
printf("%d
",ans);
return 0;
}