1. 程式人生 > 實用技巧 >PAT A1091 Acute Stroke (30分)

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;
}