【PAT】1091. Acute Stroke (30)【宽度优先搜索】

题目描述

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.

翻译:一个识别急性脑卒中的重要因素是坏掉的核心体积。给你核心区域的每个MRI薄片的影像分析结果,你的任务是计算坏掉的核心体积。

INPUT FORMAT

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.

PAT1091题图
Figure 1

翻译:每个输入文件包含一组测试数据。对于每组输入数据,第一行包括4个正整数:M,N,L和T,M和N代表每一片薄片的大小(i.e.一个薄片的像素用M*N的矩阵表示,最大分辨率为1286*128);L(<=60)是一个大脑的切片个数,T代表整数门槛(i.e.如果一圈相连的核心体积小于T,那么这一块核心将不会被计算)。
接着给出L个切片。每个切片用M*N的0/1矩阵表示,1代表一个坏死部分的像素,0代表正常部分。由于一个切片的厚度是常量,所以我们只需要计算1的个数来得到坏掉的核心体积。但是,一个大脑可能有多块分散的核心区域,并且只有那些不小于T的坏死部分会被计算。如果两个像素用一个公共面,则称它们“相连”,因此将它们算为同一区域,如图一所示的6块红色像素部分都与蓝色像素部分相连。

OUTPUT FORMAT

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


解题思路

这道题第一反应就是深度优先搜索,刷刷刷几下写完,答案正确,直接自信提交,结果报段错误。原以为是题目出错,给定的范围有问题,毕竟1286这个值怎么看都不靠谱,在网上搜了一下别人的题解后发现是因为栈溢出,深度优先搜索是栈存储的,最先的状态不抛出,累计到最后就爆栈了。而宽度优先搜索是队列存储的,先进先出,所以大大减少了存储压力。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<algorithm>
#define INF 99999999
using namespace std;
int x,y,z,T,ccount=0;
bool d[70][1290][130],v[70][1290][130]; 
struct node{
    int x,y,z;
    node(){}
    node(int xx,int yy,int zz):x(xx),y(yy),z(zz){}
};
queue<node> q;
int bfs(int a,int b,int c){
    q.push(node(a,b,c));
    v[a][b][c]=true;
    int sum=0;
    while(!q.empty()){ 
        node temp=q.front();q.pop();
        if(!d[temp.x][temp.y][temp.z])continue;
        sum++;
        a=temp.x,b=temp.y,c=temp.z;
        if(a-1>=0&&!v[a-1][b][c])q.push(node(a-1,b,c)),v[a-1][b][c]=true;
        if(a+1<z&&!v[a+1][b][c])q.push(node(a+1,b,c)),v[a+1][b][c]=true;
        if(b-1>=0&&!v[a][b-1][c])q.push(node(a,b-1,c)),v[a][b-1][c]=true;
        if(b+1<x&&!v[a][b+1][c])q.push(node(a,b+1,c)),v[a][b+1][c]=true;
        if(c-1>=0&&!v[a][b][c-1])q.push(node(a,b,c-1)),v[a][b][c-1]=true;
        if(c+1<y&&!v[a][b][c+1])q.push(node(a,b,c+1)),v[a][b][c+1]=true;
    } 
    return sum;
}
int main(){
    scanf("%d%d%d%d",&x,&y,&z,&T);
    memset(d,0,sizeof(d));
    memset(v,0,sizeof(v));
    int a;
    for(int i=0;i<z;i++){
        for(int j=0;j<x;j++){
            for(int k=0;k<y;k++){
                scanf("%d",&a);
                if(a)d[i][j][k]=true;
                else d[i][j][k]=false;
            }
        }
    }
    for(int i=0;i<z;i++){
        for(int j=0;j<x;j++){
            for(int k=0;k<y;k++){
                if(d[i][j][k]&&!v[i][j][k]){
                    int temp=bfs(i,j,k);
                    if(temp>=T)ccount+=temp;
                }
            }
        }
    }
    printf("%d\n",ccount);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/tjj1998/article/details/80249006