PAT (Advanced Level) Practice 1091 Acute Stroke BFS应用

一、概述

分块,计算各块和,和大于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);
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值