PAT 甲级 1091 Acute Stroke

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

 题意:输入4(n)*3(m)的矩阵,共5(slice)个,然后计算每个块内1的个数(块是由三维数组中相邻的1组成,只需要与块内的某个1相邻,该1就在块内);

思路:遍历所有点,找到该点所在的块的1的个数,用广度优先搜索;

模板:

//返回值根据题意要求,参数的个数根据你是几位的矩阵
int/void BFS(int x,int y,...){
    queue Q;
    Node.x=x,Node.y=y....;//对第一个结点操作;
    Q.push(Node);//首元素入队;
    while(!Q.empty()){
        取出首结点,对首结点操作;
        首结点出队;
        将该结点所能到达的所有结点入队;
    }    
}


代码:
 

#include<iostream>
#include<queue>
using namespace std;
struct node{
	int x,y,z;
}Node;
int n,m,slice,T;//n*m 的数组,共slice片; 
bool inq[1290][130][61]={false};
int pixel[1290][130][61];//三维矩阵,是由n片二维数组从0到n从下到上组成; 
int X[6]={0,0,0,0,1,-1};
int Y[6]={0,0,1,-1,0,0};//增量数组; 
int Z[6]={1,-1,0,0,0,0};

bool judge(int x,int y,int z){//判断该点是否合法; 
	if(x<0||y<0||z<0||x>=n||y>=m||z>=slice )return false;//边界问题; 
	if(inq[x][y][z]==true||pixel[x][y][z]==0)return false;//题意限制; 
	//z也是从0开始计数的; 
	return true; 
}

int BFS(int x,int y, int z){
	queue<node> Q;
	int tot=0;
	Node.x=x,Node.y=y,Node.z=z;
	Q.push(Node);//先放入,否则队列为空; 
	inq[x][y][z]=true;
	while(!Q.empty()){
		node top=Q.front();//访问首结点top; 
		Q.pop();//取出首结点; 
		tot++;//进队的终会出队,所以在这个地方计数就合适了; 
		for(int i=0;i<6;i++){//遍历结点上下左右前后这六个方向; 
			int newx=top.x+X[i];
			int newy=top.y+Y[i];
			int newz=top.z+Z[i];
			if(judge(newx,newy,newz)==true){
				Node.x=newx,Node.y=newy,Node.z=newz;
				Q.push(Node); 
				inq[newx][newy][newz]=true;
			}
		}
	}
	if(tot>=T)return tot;
	else return 0;
}
int main( ){
	scanf("%d %d %d %d",&n,&m,&slice,&T);
	for(int z=0;z<slice;z++){
		for(int x=0;x<n;x++){
			for(int y=0;y<m;y++){
				scanf("%d",&pixel[x][y][z]);
			}
		}
	}
	int ans=0;//总个数; 
	for(int z=0;z<slice;z++){
		for(int x=0;x<n;x++){
			for(int y=0;y<m;y++){
				if(pixel[x][y][z]==1&&inq[x][y][z]==false){
					ans+=BFS(x,y,z);//以这点坐标作六个方向的伸展,如果是1就标记(标记的目的是防止同一块内的结点伸展有相同部分而导致的重复计数)否则就跳过,从而算出块内1的个数; 
				} 
			}
		}
	}
	printf("%d",ans);
	return 0;	
}
//本质上bfs是一个入队出队的过程,按照着一个特定的规则入队就是广度优先搜索; 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值