PAT A1091 Acute Stroke (30分)



脑子由薄片组成,MxN是一片薄片的长与宽,L是片数,T是单个中风核心的体积的阈值。
若三维矩阵中有若干个邻接的像素1,则这些像素1构成了1块中风核心。
可能出现多个中风核心区域,必须满足条件:单个体积>=T,求中风核心的总体积之和。
注意:

  • 矩阵数据的输入是按层按行按列的
  • 三维数组matrix记录输入的0、1数据;三维数组v记录对应像素是否被访问;
  • 遍历每一个像素1,查看其是否被访问,查看和它邻接的6个像素是否为1且是否被访问过,继续查看与邻接像素们邻接的像素是否被访问过。。直到找不到与他们邻接的像素,确定了一个“块”。
  • 继续遍历每一个像素1,重复以上步骤,直到遍历完所有像素1,得出总块数。
  • judge函数判断该像素是否需要访问:是否出界(边界像素的邻接像素不到6个),像素是否为1,是否已被访问。
  • 确定一个“块”时运用队列:
  1. 遍历每一个像素1,查看其是否被访问,若没有则进入队列;
  2. 取队头元素,查看和它邻接的6个像素是否为1且是否被访问过,没有则进入队列并设置为被访问。
  3. 重复步骤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\n",ans);
    return 0;
}
posted @ 2020-09-02 17:33  是水泵呢  阅读(137)  评论(0编辑  收藏  举报