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×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×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
识别急性脑卒中的一个重要因素是卒中核心的体积。根据图像分析的结果,在每个MRI切片中识别核心区域,您的工作是计算中风核心的体积。
输入规范:每个输入文件包含一个测试用例。对于每种情况,第一行包含 4 个正整数:M、N、L 和 T,其中 M 和 N 是每个切片的大小(即切片的像素在 M×N 矩阵中,最大分辨率为 1286 x 128);L(≤60)是大脑切片的数量;T是整数阈值(即,如果连接核心的体积小于T,则不得计算该核心)。 然后给出L切片。每个切片由 0 和 1 的 M×N 矩阵表示,其中 1 表示笔触像素,0 表示正常。由于切片的厚度是一个常数,我们只需要计算 1 的数量即可获得体积。然而,大脑中可能有几个分离的核心区域,只有那些体积不小于T的区域才被计算在内。两个像素是连接的,因此如果它们共享一个公共侧,则属于同一区域,如图 1 所示,其中所有 6 个红色像素都连接到蓝色像素。
输出规范:对于每种情况,在一行中输出中风核心的总体积。
题目核心和关键把握:
注意是中风核心体积,也就是不计入一个0(正常的核心)
同时不能直接遍历出现1的情况,因为我们是求区域的体积,而区域的定义就是他们处于同一个公共侧,只能是每个点的上下左右前后是1的数才能联通,非1就不属于,一直这样每个点按照上下左右前后延展下去。
不从0开始讨论和搜索到0时剪枝是因为到0是不符合题意的,因为我们要求的是中风核心体积。其实就是隐藏条件,所有连接核心都必须是1不能有0.如果存在了0还讨论什么?
直接全部作为一个整体,全部1都输出都可以了。
题目的图片就是这个意思,公共侧就是所有元素都必须满足条件即都为中风像素才能连接。而一旦出现0就立马分开,表示不与0为一个区域,于是就通过0划分了很多个区域,而这些区域就必须满足不小于t,小于的就不算了。
根据题目,像素之间是连接的,而6个像素连接一个像素明确了像素连接的方向也就是上下左右前后。因此只要一直不遇到0那么一直朝这几个方向连接他们都是一个公共侧,遇到0就封闭划边界,一直到结束,就划分了一个区域。
每一次的BFS,附近能联通的元素都联通了。
那么剩下的就只能是独立的不同区域,不会与前面一个区域的所有的像素有任何的相关性和连接。
因此没有必要担心前面先标记了元素的会影响后面区域的结果。
L其实就相当于高度,有多少层切片的意思。把所有切片叠在一起就是总体积(不是行程核心体积)
一个点就表示像素
计算入一个1就相当于获得了体积1
还有就是这个上下左右前后就意味着一定要把L看成高度,看成一个立体,上下的点计算公共侧的时候是要用到的,不能忽略!
因此,立体图形--三维数组;每一次都要检测上下左右前后,BFS
这题目感觉非常难读懂,最难的就在于审题,题目读懂了问题就很好解决了,
对于像这种类似的问题,一定要认真审题,不能理解错误,不然怎么解题都是错的
看起来审题好像不是回事,实际上等理解错题意,实现了错误的方法--这段代码就会前功尽弃,错误的理解做出错误的方法也只是做了无用功,这是很可惜的。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<map>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int m, n, l, t;
int stroke[1300][130][65];
bool visited[1300][130][65] = { false };
int TX[6] = { 0,0,1,-1,0,0 };
int TY[6] = {1,-1,0,0,0,0 };
int TZ[6] = {0,0,0,0,1,-1};
struct node
{
int x, y, z;
};
bool judge(int x,int y,int z)
{
if (x < 0 || x >= m || y < 0 || y >= n || z < 0 || z >= l)
return false;
if (stroke[x][y][z] == 0 || visited[x][y][z])
return false;
return true;
}
int bfs(int i, int j, int k)
{
visited[i][j][k] = true;
int cnt = 1;//记录当前传入的点
node pixel;
pixel.x = i;
pixel.y = j;
pixel.z = k;
queue<node>q;
q.push(pixel);
while (!q.empty())
{
pixel = q.front();
q.pop();//忘了出队了难怪死循环
for (int i = 0; i < 6; i++)
{
int tx = pixel.x+TX[i];
int ty= pixel.y + TY[i];
int tz = pixel.z + TZ[i];
if (judge(tx, ty, tz))
{
cnt++;
visited[tx][ty][tz] = true;
q.push({ tx,ty,tz });
//直接传三个参数也可以的,系统会自动给你一个新的node
}
}
}
return cnt >= t ? cnt : 0;
}
int main()
{
long ans = 0;
cin >> 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", &stroke[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 (stroke[i][j][k] && !visited[i][j][k])
ans += bfs(i, j, k);
}
cout << ans;
return 0;
}