1091 Acute Stroke 需再做

Posted CSU迦叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1091 Acute Stroke 需再做相关的知识,希望对你有一定的参考价值。

这是BFS的典型应用场景:求给定矩阵中块(由相邻的点组成)的大小之和。不同的是这一次是三维。

判断是否邻接的依据是是否有公共边,还是可以用上增量数组的技巧

int X[6] = {0,0,1,-1,0,0};//增量数组 
int Y[6] = {1,-1,0,0,0,0};
int Z[6] = {0,0,0,0,1,-1};

总体思路是,用一个和输入形状完全一样的in queue数组判断每个点是否已经进过队列,以防重复计算。

对输入数组开始遍历,如果一个点既为1又没进过inq,对其进行BFS。

BFS的作用是返回当前区域的大小,注意一开始size的初值设为1而不是0,因为至少有目前这个结点是1,最后返回时如果低于阈值就返回0(这样外层可以直接加上),如果达到阈值就返回size。

//BFS函数的任务是访问(x,y,z)中的块中的所有节点,返回块的大小 
int BFS(int x,int y,int z){
	int size = 1;//该结点自身 
	queue<Node> que;//定义队列
	node.x = x;//赋予当前结点坐标 
	node.y = y;
	node.z = z;
	que.push(node);//起点入队
	inq[x][y][z] = true;
	while(!que.empty()){
		Node top = que.front();//取出队首元素
		que.pop();//队首元素出队
		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)){//判断是否能够入队
				size ++;//该区域又一次壮大 
				node.x = newX;
				node.y = newY;
				node.z = newZ;
				que.push(node);//node入队
				inq[newX][newY][newZ]= true;//设置node已经入队 
			}
		}
	}
	if(size>=t)return size;
	else return 0; 
}

易错点:三层循环的位置错误

应对办法:想想哪些维度在变,哪些不变

AC代码

#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<cstring>
#include<iostream>
#include<vector>
#include<stack>
#include<queue>
#include<algorithm>

using namespace std;

const int maxn = 100;

struct Node{
	int x,y,z;//坐标(x,y,z) 
}node;//临时结点

int m,n,l;//行和列和层
int t;//区域大小的下限 
int brain[1286][128][60];//存放脑切片的情况 
bool inq[1286][128][60] = {false};//是否已经入过BFS的队列 
int X[6] = {0,0,1,-1,0,0};//增量数组 
int Y[6] = {1,-1,0,0,0,0};
int Z[6] = {0,0,0,0,1,-1};

//判断当前位置是否能够入队
bool judge(int x,int y,int z){
	//越界,不行
	if(x<0||x>=n||y<0||y>=m||z<0||z>=l)return false;
	//不是1,不行
	if(!brain[x][y][z])return false; 
	//已经入过了,不行
	if(inq[x][y][z])return false;
	
	return true; 
}

//BFS函数的任务是访问(x,y,z)中的块中的所有节点,返回块的大小 
int BFS(int x,int y,int z){
	int size = 1;//该结点自身 
	queue<Node> que;//定义队列
	node.x = x;//赋予当前结点坐标 
	node.y = y;
	node.z = z;
	que.push(node);//起点入队
	inq[x][y][z] = true;
	while(!que.empty()){
		Node top = que.front();//取出队首元素
		que.pop();//队首元素出队
		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)){//判断是否能够入队
				size ++;//该区域又一次壮大 
				node.x = newX;
				node.y = newY;
				node.z = newZ;
				que.push(node);//node入队
				inq[newX][newY][newZ]= true;//设置node已经入队 
			}
		}
	}
	if(size>=t)return size;
	else return 0; 
} 


int main(){
	
	scanf("%d%d%d%d",&n,&m,&l,&t);
	for(int k=0;k<l;k++){
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				scanf("%d",&brain[i][j][k]);
			}
		}
	}
	
	int ans = 0;
	
	for(int k=0;k<l;k++){
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(brain[i][j][k]&&!inq[i][j][k]){
					ans += BFS(i,j,k);
				}
			}
		}
	}

	printf("%d\\n",ans);
	 
	return 0;
}

以上是关于1091 Acute Stroke 需再做的主要内容,如果未能解决你的问题,请参考以下文章

PAT1091:Acute Stroke

1091. Acute Stroke (30)搜索——PAT (Advanced Level) Practise

1091. Acute Stroke (30)搜索——PAT (Advanced Level) Practise

1091 Acute Stroke

PAT甲级1091 Acute Stroke (30分)

PAT 1091 Acute Stroke [难][bfs]