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 需再做的主要内容,如果未能解决你的问题,请参考以下文章
1091. Acute Stroke (30)搜索——PAT (Advanced Level) Practise