一、概述
分块,计算各块和,和大于t的相加,然后输出。
DFS会爆栈,因此使用BFS较好。
需要使用三维数组,两个。第一个存储0或者1,第二个存储是否入过队列。注意,第一个类型为int,第二个为bool,如果第二个也是int会内存溢出。
一定要注意三维数组A[z][y][x]的下标的含义。
我是按一行然后一片那样输入的,因此z表示竖坐标,y表示纵坐标,x表示横坐标。这个很容易就晕了。
二、分析
首先是输入:
for (k = 0; k<L; k++)
{
for (j = 0; j<M; j++)
{
for (i = 0; i<N; i++)
scanf("%d", &stroke[k][j][i]);
}
}
层数在最外面,然后是行数,最后是列数。这样输入就和正常的想法一样。
然后是BFS:
void BFS(int z, int y, int x, int tempSum)
{
queue<Node> q;
node.x = x;
node.y = y;
node.z = z;
q.push(node);
inq[z][y][x] = true;
while (!q.empty())
{
Node top = q.front();
q.pop();
tempSum++;
int i, j, k;
for (i = 0; i < 3; i++)
{
if (valid(top.x + zuo[i], top.y, top.z) == 1)
{
Node validNode;
validNode.x = top.x + zuo[i];
validNode.y = top.y;
validNode.z = top.z;
q.push(validNode);
inq[validNode.z][validNode.y][validNode.x] = true;
}
if (valid(top.x, top.y + qian[i], top.z) == 1)
{
Node validNode;
validNode.x = top.x;
validNode.y = top.y + qian[i];
validNode.z = top.z;
q.push(validNode);
inq[validNode.z][validNode.y][validNode.x] = true;
}
if (valid(top.x, top.y, top.z + shang[i]) == 1)
{
Node validNode;
validNode.x = top.x;
validNode.y = top.y;
validNode.z = top.z + shang[i];
q.push(validNode);
inq[validNode.z][validNode.y][validNode.x] = true;
}
}
}
if (tempSum >= T)
{
sum += tempSum;
}
}
BFS需要使用队列实现,很直观,比DFS的递归简单些。考虑到进出队列的是三维坐标,因此队列元素应该是一个结构体,这一点要注意。
定死的是先开一个队列,把头结点push进去,进队列数组置为true。
然后进入循环。将队列头拿出,pop,递增sum;
然后逻辑判断,将节点放入队列即可。每放入一个节点,进队列数组都要改一下。即,push后接true。循环退出条件是队列为空。判断是否进队列一般是一个函数。
然后使用BFS即可。与DFS不同,DFS只需要调用一次即可,而BFS是要遍历,判断是否需要调用,即极端情况下要调用许多次。一定要注意判断是否调用,否则很容易超时。
如下:
for (k = 0; k<L; k++)
{
for (j = 0; j<M; j++)
{
for (i = 0; i<N; i++)
{
if (valid(i, j, k))
BFS(k, j, i, 0);
}
}
}
三、总结
BFS也是很重要的算法,如何写要记住。
PS:代码如下
#include<stdio.h>
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<queue>
using namespace std;
int shang[3] = { -1,0,1 };
int zuo[3] = { -1,0,1 };
int qian[3] = { -1,0,1 };
int M, N, L, T;
int stroke[100][1290][130] = { 0 };
bool inq[100][1290][130] = { false };
int sum = 0;
struct Node
{
int x, y, z;
}node;
int valid(int x, int y, int z)
{
if (x >= N || y >= M || z >= L || x<0 || y<0 || z<0)
return 0;
else if (inq[z][y][x] == true)
return 0;
else if (stroke[z][y][x] == 0)
return 0;
else
return 1;
}
void BFS(int z, int y, int x, int tempSum)
{
queue<Node> q;
//if (valid(x, y, z) == 0)
// return;
//else
//{
node.x = x;
node.y = y;
node.z = z;
q.push(node);
inq[z][y][x] = true;
while (!q.empty())
{
Node top = q.front();
q.pop();
tempSum++;
int i, j, k;
for (i = 0; i < 3; i++)
{
if (valid(top.x + zuo[i], top.y, top.z) == 1)
{
Node validNode;
validNode.x = top.x + zuo[i];
validNode.y = top.y;
validNode.z = top.z;
q.push(validNode);
inq[validNode.z][validNode.y][validNode.x] = true;
}
if (valid(top.x, top.y + qian[i], top.z) == 1)
{
Node validNode;
validNode.x = top.x;
validNode.y = top.y + qian[i];
validNode.z = top.z;
q.push(validNode);
inq[validNode.z][validNode.y][validNode.x] = true;
}
if (valid(top.x, top.y, top.z + shang[i]) == 1)
{
Node validNode;
validNode.x = top.x;
validNode.y = top.y;
validNode.z = top.z + shang[i];
q.push(validNode);
inq[validNode.z][validNode.y][validNode.x] = true;
}
}
/*for (j = 0; j<3; j++)
for (k = 0; k<3; k++)
{
if (valid(top.x + zuo[i], top.y + qian[j], top.z + shang[k]) == 1)
{
Node validNode;
validNode.x = top.x + zuo[i];
validNode.y = top.y + qian[j];
validNode.z = top.z + shang[k];
q.push(validNode);
inq[validNode.z][validNode.y][validNode.x] = true;
}
}*/
}
if (tempSum >= T)
{
//printf("tempsum=%d", tempSum);
sum += tempSum;
}
//}
}
int main()
{
scanf("%d%d%d%d", &M, &N, &L, &T);//M1286N128,3452
int i, j, k;
for (k = 0; k<L; k++)
{
for (j = 0; j<M; j++)
{
for (i = 0; i<N; i++)
scanf("%d", &stroke[k][j][i]);
}
}
for (k = 0; k<L; k++)
{
for (j = 0; j<M; j++)
{
for (i = 0; i<N; i++)
{
if (valid(i, j, k))
BFS(k, j, i, 0);
}
}
}
printf("%d", sum);
}