solution Of 1091. Acute Stroke (30)

48 篇文章 0 订阅

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.

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:题目其实不复杂,但由于部分数据量较大,在用递归的方式计算时,可能会暴栈;
要求2:三维数据的链接表示为二维图中的“4联通”的方式,对于斜对角的连接性不做考虑。

程序步骤:
第一步、读入三维数组;
第二步、对于值为1的元素,开始遍历周围的点,将遍历到的连接部分的点标记为0,并统计标记的数量;
第三步、对于统计的标记数量大于阈值的判定为中风区。
第四步、累加中风区的体积,输出即可。

具体程序(递归,最后两个case暴栈)如下:

#include <iostream>
#include <cstring>
#include <cstdlib>
#define M 1300
#define N 130
#define S 65
using namespace std;
int width,height,sli,threshold;
int pics[S][M][N];
int floodfill(int k,int i,int j)//深度优先,最后的两个大case会无法通过,程序暴栈
{
    int area=1;
    pics[k][i][j]=2;
    if(k>0&&pics[k-1][i][j]==1)
        area+=floodfill(k-1,i,j);
    if(k+1<sli&&pics[k+1][i][j]==1)
        area+=floodfill(k+1,i,j);
    if(i>0&&pics[k][i-1][j]==1)
        area+=floodfill(k,i-1,j);
    if(i+1<height&&pics[k][i+1][j]==1)
        area+=floodfill(k,i+1,j);
    if(j>0&&pics[k][i][j-1]==1)
        area+=floodfill(k,i,j-1);
    if(j+1<width&&pics[k][i][j+1]==1)
        area+=floodfill(k,i,j+1);
    return area;
}
int main() {
    // your code goes here
    cin>>height>>width>>sli>>threshold;
    int i,j,k;
    memset(pics,0,sizeof(pics));
    for(k=0;k<sli;++k)
        for(i=0;i<height;++i)
            for(j=0;j<width;++j)
                cin>>pics[k][i][j];
    int count=0;
    int area;
    for(k=0;k<sli;++k)
        for(i=0;i<height;++i)
            for(j=0;j<width;++j)
                if(pics[k][i][j]==1)
                {
                    area=floodfill(k,i,j);
                    if(area>=threshold)
                        count+=area;
                }
    cout<<count<<endl;
    return 0;
}

具体程序(AC,迭代的形式)如下:

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <queue>
#define M 1300
#define N 130
#define S 65
using namespace std;
int width,height,sli,threshold;
struct pixel{
    int k;
    int i;
    int j;
    pixel(int k,int i, int j):k(k),i(i),j(j){}  
};
int roundK[6]={-1,1,0,0,0,0};
int roundI[6]={0,0,-1,1,0,0};
int roundJ[6]={0,0,0,0,-1,1};
queue<pixel> vec;
int pics[S][M][N];
bool range(int k,int i,int j)
{
    if(k>=0&&k<sli)
        if(i>=0&&i<height)
            if(j>=0&&j<width)
                return true;
    return false;
}
int floodfill(int k,int i,int j)//深度优先,最后的两个大case会无法通过,程序暴栈
{
    int area=1;
    pics[k][i][j]=0;
    vec.push(pixel(k,i,j));
    while(!vec.empty())
    {
        pixel tmp=vec.front();
        vec.pop();
        for(int i=0;i<6;++i)
        {
            int tk=tmp.k+roundK[i];
            int ti=tmp.i+roundI[i];
            int tj=tmp.j+roundJ[i];
            if(range(tk,ti,tj)&&pics[tk][ti][tj])
            {
                vec.push(pixel(tk,ti,tj));
                pics[tk][ti][tj]=0;
                ++area;
            }
        }
    }
    return area;
}
int main() {
    // your code goes here
    cin>>height>>width>>sli>>threshold;
    int i,j,k;
    while(!vec.empty())
        vec.pop()
    memset(pics,0,sizeof(pics));
    for(k=0;k<sli;++k)
        for(i=0;i<height;++i)
            for(j=0;j<width;++j)
                cin>>pics[k][i][j];
    int count=0;
    int area;
    for(k=0;k<sli;++k)
        for(i=0;i<height;++i)
            for(j=0;j<width;++j)
                if(pics[k][i][j]==1)
                {
                    area=floodfill(k,i,j);
                    if(area>=threshold)
                        count+=area;
                }
    cout<<count<<endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值