考查点:BFS
思路:本质上就是立体的广搜,理论上深搜也可以但是会溢出,所以以后还是尽量用广搜,只要设置六个方向的三个数组,之后基本套路,用标记数组标记入队,每次出队时将设置的计数器自增,细节上注意小于t的是不需要计入的,最后在主函数上遍历时在合法节点上调用bfs,并更新ans
提交情况:第一次因为开的三维数组有一维开小了,但答案没有报段错误,以后要注意。。
收获:这类搜索题基本代码都差不多,记住几个关键点:方向数组,BFS,标记数组,还有判断函数
#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#define FOR(i, x, y) for(int i = x; i < y; i++)
#define rFOR(i, x, y) for(int i = x; i > = y; i--)
#define MAXN 10005
#define oo 0x3f3f3f3f
using namespace std;
int m,n,l,t;
int pi[66][1290][130];
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};
int inq[66][1290][130];
struct node{
int x,y,z;
}Node;
bool judge(int x,int y,int z){
if(x<0 || y<0||z<0) return false;
if(x>=l||y>=m||z>=n) return false;
if(inq[x][y][z]||pi[x][y][z]==0) return false;
return true;
}
int BFS(int x,int y,int z){
int tot=0;
queue<node> q;
Node.x=x,Node.y=y,Node.z=z;
q.push(Node);
inq[x][y][z]=1;
while(!q.empty()){
node top=q.front();
q.pop();
tot++;
FOR(i,0,6){
int nx=top.x+X[i];
int ny=top.y+Y[i];
int nz=top.z+Z[i];
if(judge(nx,ny,nz)){
Node.x=nx,Node.y=ny,Node.z=nz;
q.push(Node);
inq[nx][ny][nz]=1;
}
}
}
if(tot>=t)return tot;
else return 0;
}
int main()
{
#ifdef LOCAL
freopen("data.in","r",stdin);
freopen("data.out","w",stdout);
#endif // LOCAL
scanf("%d%d%d%d",&m,&n,&l,&t);
FOR(i,0,l)
FOR(j,0,m)
FOR(k,0,n){
scanf("%d",&pi[i][j][k]);
}
int ans=0;
FOR(i,0,l)
FOR(j,0,m)
FOR(k,0,n){
if(pi[i][j][k]==1&&inq[i][j][k]==false)
ans+=BFS(i,j,k);
}
printf("%d",ans);
return 0;
}