PAT A1091 Acute Stroke (30分)
阿新 • • 發佈:2020-09-02
腦子由薄片組成,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\n",ans); return 0; }