PAT 1091 Acute Stroke

 

下面会有中文解释     下面会有中文解释      下面会有中文解释

                                                                       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×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

题目大意:

判断一个人是否得了急性脑卒中的重要方式就是看他中风核心区的体积,我们建立一个图像模型,将模型分片(分层),分为L(<=60)片,每片的像素大小是 M x N 大小(长x宽)(M<=1286,N<=128), 像素点(值为1)以及它的相邻像素点(值也为1)以及它的相邻像素点的相邻像素点(值为1)以及继续相邻的那些像素点的个数如果超过了T(阀值),则该区域为中风核心区,我们需要计算在内。

有一个三维的图像像素模型, 模型中每个像素点的值为1或者0,每个像素点的相邻像素点包括上下左右前后六个方向的像素点,也就是说除了边缘上的像素点之外每个像素点有六个相邻像素点。

若干个相邻的“1”称为一个“块”(不必两两相邻,只要与块中某一个“1”相邻,该“I”就在块中)。而如果某个块中的“1”的个数不
低于T个,那么称这个块为“卒中核心区"。现在需要求解所有卒中核心区中的1的个数之和。

输入:

四个整数:N,M,L,T

接下来有L个片,每个片有N行M列。

输出:

卒中核心区的体积 (卒中核心区中的1的个数之和)

#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<map>
#include<unordered_map>
#include<set>
#include<sstream>
using namespace std;
const int MAXN = 1290; 
const int MAXM = 130;
const int MAXL = 60;

struct Node{
	int x;
	int y;
	int z;
	Node(int x,int y,int z){
		this->x = x;
		this->y = y;
		this->z = z;
	}
};
//矩阵为n*m型,共有l层,某个块中1的个数超过t才算是卒中核心区。 
int n,m,l,t; 
int pixels[MAXN][MAXM][MAXL]; //像素点分布 
bool vis[MAXN][MAXM][MAXL] = {false}; //(x,y,z)像素点是否已访问过 
//上 下  左  右  前  后 中x,y,z改变的值 
int xc[6] = {0,0 ,0 ,0,1,-1};
int yc[6] = {0,0 ,-1,1,0,0};
int zc[6] = {1,-1,0 ,0,0,0}; 
queue<Node> que;

//判断某个像素点是否超出范围 
bool judge(int x,int y,int z){
	if(x<0||x>=n||y<0||y>=m||z<0||z>=l){
		return false;	
	}	
	return true; 
}

int BFS(int x,int y,int z){
	int num = 0; //一次BFS找到的stroke core(卒中核心区)的体积。 
	/*
	**注意点:vis表示的是已访问,而不是已进栈,
	**就算程序过程中这个节点又被弹出栈,它的vis值也仍然为true。 
	**/
	if(!vis[x][y][z] && pixels[x][y][z]==1){
		que.push(Node(x,y,z));
		vis[x][y][z] = true;
		num++;
	}
	while(!que.empty()){
		/*
		** 误区:这个地方不能写成Node &node
		** 也就是不能用引用,否则会有两个样例通过不了
		** 我也很郁闷。。。 
		*/
		Node node = que.front();
		que.pop();
		for(int i=0;i<6;i++){
			int nx = node.x + xc[i];
			int ny = node.y + yc[i];
			int nz = node.z + zc[i];
			if(judge(nx,ny,nz) && !vis[nx][ny][nz] && pixels[nx][ny][nz]==1){
				que.push(Node(nx,ny,nz));
				vis[nx][ny][nz] = true;
				num++;
			}
		}
	}
	if(num < t){
		num = 0;
	}
	return num;
}

int main(){ 
	cin>>n>>m>>l>>t;
	for(int z=0;z<l;z++){
		for(int x=0;x<n;x++){
			for(int y=0;y<m;y++){
				cin>>pixels[x][y][z];
			}
		}
	} 
	int sum = 0;
	for(int z=0;z<l;z++){
		for(int x=0;x<n;x++){
			for(int y=0;y<m;y++){
				//BFS的功能: 
				//看一下(x,y,z)这个像素点是不是卒中核心区
				//如果是的话返回它的体积(值为1的像素点的个数) 
				sum += BFS(x,y,z);
			}
		}
	} 
	cout<<sum<<endl;
	return 0; 
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值