1091 Acute Stroke (30 point(s)) PAT甲级

1091 Acute Stroke (30 point(s))

BFS

题目

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.

figstroke.jpg

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

思路

题意

看了15分钟没有看懂题目…然后搜索了一下,看了别人的解法也没很懂,跟着解法自己把sample求了一遍终于懂了OTL

题目给出的m,n相当于切片的x,y轴大小,L是切片的数量,其实L就是z轴大小(这个看题目的时候真没有理解到…)。这样相当于给出了一系列大脑切片的坐标,1代表中风0代表正常。t是可以被评估的core region的最小大小,这个core region看了几遍没懂是什么,一开始还以为每个m*n的切片叫core region,以为那张连起来的6+1个切片是邻边相等即可连接的意思(但这样理解就会出现很多相等的邻边,感觉很不好判断)。后来才明白那个6+1的方片是6+1个坐标点,意思是蓝色点的上下左右前后六个方向算是邻接区域。相当于每团stroke块中的stroke volume要大于t,这里的stroke volume才可以计算到总的结果中。

分析

题意理解了后代码其实很简单,用三维数组记录坐标,BFS判断出邻接区域即可。

X[6],Y[6],Z[6]用来记录每次邻接坐标需要在原坐标上移动的距离。这样只要用一层循环即可遍历所有的邻接坐标。

judge函数用来判断该邻接坐标是合法的非访问stroke结点,是则归入同一块中。

代码

#include<iostream>
#include<queue>
using namespace std;

int m, n, l, t, ans = 0;
int stroke[1300][130][65];
bool visit[1300][130][65] = { false };
int X[6] = { 1,-1,0,0,0,0 };
int Y[6] = { 0,0,1,-1,0,0 };
int Z[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 || visit[x][y][z]) return false;
	return true;
}

int bfs(int x, int y, int z) {
	visit[x][y][z] = true;
	int cnt = 1;
	node temp;
	queue<node> q;
	temp.x = x;
	temp.y = y;
	temp.z = z;
	q.push(temp);
	while (!q.empty()) {
		temp = q.front();
		q.pop();
		for (int i = 0; i < 6; ++i) {
			int tx = temp.x + X[i];
			int ty = temp.y + Y[i];
			int tz = temp.z + Z[i];
			if (judge(tx, ty, tz)) {
				visit[tx][ty][tz] = 1;
				cnt++;
				q.push({ tx,ty,tz });
			}
		}
	}
	return cnt >= t ? cnt : 0;
}

int main()
{
	scanf("%d%d%d%d", &m, &n, &l, &t);
	for (int i = 0; i < l; ++i) {
		for (int j = 0; j < m; ++j) {
			for (int k = 0; k < n; ++k)
				scanf("%d", &stroke[j][k][i]);
		}
	}
	for (int i = 0; i < l; ++i) {
		for (int j = 0; j < m; ++j) {
			for (int k = 0; k < n; ++k)
				if (stroke[j][k][i] == 1 && !visit[j][k][i])
					ans += bfs(j, k, i);
		}
	}
	printf("%d\n", ans);
	return 0;
}

注意

  • 坐标的对应关系(x-m, y-n, z-l)不要混淆。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值