1091. Acute Stroke (30) BFS or DFS

来源:互联网 发布:爱奇艺显示网络未连接 编辑:程序博客网 时间:2024/04/29 14:03

1091. Acute Stroke (30)

时间限制
400 ms
内存限制
65536 kB
代码长度限制
16000 B
判题程序
Standard
作者
CHEN, Yue

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 21 1 1 11 1 1 11 1 1 10 0 1 10 0 1 10 0 1 11 0 1 10 1 0 00 0 0 01 0 1 10 0 0 00 0 0 00 0 0 10 0 0 11 0 0 0
Sample Output:
26

        先简述一下题意,给你一个由0和1组成的三维的数组,计算每个由1填充的连通区域中的1的个数,连通的概念可以很容易从题目中那幅图理解,如果个数大于给定的t就将这一区域中的1的个数累加到最终的ans中,最后输出ans,感觉这道题目最难的根本不是编程,而是生词太多。解决的方法无外乎DFS和BFS两种。解法是对每个含有1的点进行搜索,搜索的时候注意不要越界就好了。然后一点微不足道的小技巧是,将三个方向上的位移用dx,dy,dz三个数组表示,

int dx[6] = {1,-1,0,0,0,0};
int dy[6] = {0,0,1,-1,0,0};
int dz[6] = {0,0,0,0,1,-1};、

       这样在求解连通的方块的时候可以使用一个for循环解决,很久以前我并不知道这种方法,在二维的图中每次都是把同样的代码写四遍,那真是一段黑暗的历史。下面是BFS的代码,使用了STL中的queue,将搜索到的每一个值为1的点入队,下一轮搜索的时候则从队列中再取出一个点进行搜索,简单愉快。

       

# include <cstdio># include <queue>using std::queue;int map[1286][128][60];struct loca{    int x,y,z;    loca(int _x,int _y,int _z):x(_x),y(_y),z(_z){}};int m,n,l,t;int dx[6] = {1,-1,0,0,0,0};int dy[6] = {0,0,1,-1,0,0};int dz[6] = {0,0,0,0,1,-1};int ans = 0;int InRange(int x,int y,int z){    return x<m&&x>=0&&y<n&&y>=0&&z<l&&z>=0;}void bfs(int x,int y,int z){    int ret = 0;queue<loca> que;que.push(loca(x,y,z));map[x][y][z] = 0;ret++;while (!que.empty()){    loca tp = que.front();que.pop();    x = tp.x;     y = tp.y;     z = tp.z;    for (int i=0;i<6;i++)    {    int nx = x + dx[i];    int ny = y + dy[i];    int nz = z + dz[i];        if (InRange(nx,ny,nz)&&map[nx][ny][nz] == 1)        {        map[nx][ny][nz] = 0;ret++;que.push(loca(nx,ny,nz));        }}} if (ret>=t)    ans += ret;}int main(){    scanf("%d%d%d%d",&m,&n,&l,&t);    for (int k=0;k<l;k++)    for (int i=0;i<m;i++)        for (int j=0;j<n;j++)            scanf("%d",&map[i][j][k]);    for (int k=0;k<l;k++)    for (int i=0;i<m;i++)        for (int j=0;j<n;j++)            if (map[i][j][k]==1)                bfs(i,j,k);    printf("%d\n",ans);    return 0;}


1 0