A1091. Acute Stroke
One important factor to identify acute stroke (急性脑卒中) is the volume of the stroke core. Given the results of image analysis in which the core regions are identified in each MRI slice, your job is to calculate the volume of the stroke core.
Input Specification:
Each input file contains one test case. For each case, the first line contains 4 positive integers: M, N, L and T, where M and N are the sizes of each slice (i.e. pixels of a slice are in an M by N matrix, and the maximum resolution is 1286 by 128); L (<=60) is the number of slices of a brain; and T is the integer threshold (i.e. if the volume of a connected core is less than T, then that core must not be counted).
Then L slices are given. Each slice is represented by an M by N matrix of 0's and 1's, where 1 represents a pixel of stroke, and 0 means normal. Since the thickness of a slice is a constant, we only have to count the number of 1's to obtain the volume. However, there might be several separated core regions in a brain, and only those with their volumes no less than T are counted. Two pixels are "connected" and hence belong to the same region if they share a common side, as shown by Figure 1 where all the 6 red pixels are connected to the blue one.
Figure 1
Output Specification:
For each case, output in a line the total volume of the stroke core.
Sample Input:
3 4 5 2 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 0
Sample Output:
26
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<vector> 5 #include<queue> 6 using namespace std; 7 int data[61][1287][129], inqu[61][1287][129]; 8 int M, N, L, T; 9 int X[6] = {1,-1,0,0,0,0}, Y[6] = {0,0,1,-1,0,0}, Z[6] = {0,0,0,0,1,-1}; 10 typedef struct NODE{ 11 int x, y, z; 12 }node; 13 int judge(node nd){ 14 if(nd.x < 0 || nd.x >= M || nd.y < 0 || nd.y >= N || nd.z < 0 || nd.z >= L) 15 return 0; 16 else if(inqu[nd.z][nd.x][nd.y] == 1 || data[nd.z][nd.x][nd.y] == 0) 17 return 0; 18 else return 1; 19 } 20 int bfs(int x, int y, int z){ 21 queue<node> Q; 22 node nd = {x, y, z}; 23 int cnt = 0; 24 if(judge(nd) == 1){ 25 Q.push(nd); 26 inqu[nd.z][nd.x][nd.y] = 1; 27 } 28 while(Q.empty() == false){ 29 node temp = Q.front(); 30 Q.pop(); 31 cnt++; 32 node temp2; 33 for(int i = 0; i < 6; i++){ 34 temp2.x = temp.x + X[i]; 35 temp2.y = temp.y + Y[i]; 36 temp2.z = temp.z + Z[i]; 37 if(judge(temp2) == 1){ 38 inqu[temp2.z][temp2.x][temp2.y] = 1; 39 Q.push(temp2); 40 } 41 } 42 } 43 if(cnt < T) 44 cnt = 0; 45 return cnt; 46 } 47 int main(){ 48 int ans = 0; 49 scanf("%d%d%d%d", &M, &N, &L, &T); 50 for(int i = 0; i < L; i++) 51 for(int j = 0; j < M; j++) 52 for(int k = 0; k < N; k++){ 53 scanf("%d", &data[i][j][k]); 54 inqu[i][j][k] = 0; 55 } 56 for(int i = 0; i < L; i++) 57 for(int j = 0; j < M; j++) 58 for(int k = 0; k < N; k++) 59 ans += bfs(j, k, i); 60 printf("%d", ans); 61 return 0; 62 }
总结:
1、本题题意:给出一个立方体,当连成一片的1的个数大于等于T时,这一块1被视为core。题目要求出大于T的1的总数量。注意是1的总数量而不是连片区的区数。使用三维数组存储数据,data[Z][X][Y],第一个Z记录层数,后面的X、Y才是每一层的数据。 可以使用bfs搜索,并记录连成一片的数量,当它>=T时,才返回本身的值,否则返回0。
2、使用inqu数组标记曾进入过队列的元素(不是访问过的元素),注意不要忘记给初始进入队列的元素坐标系,不要忘记检查第一个元素的合法性。
3、可以进入队列的条件:之前没有进入过的,且在合法的xyz区域内,且自身的data数据为1。
4、偏移数组:X[6] = {1,-1,0,0,0,0}, Y[6] = {0,0,1,-1,0,0}, Z[6] = {0,0,0,0,1,-1}; 可以使用循环来列举上下左右前后6个方位,初始化的方法是:当X为1或-1时,其它两个必须是0。