PAT甲级1091 Acute Stroke (30分) 练习BFS

BFS:

当碰到岔道口时,依次访问从该岔道口出发能直接到达的所有节点,并用队列存储待访问节点。

注意点:

(1)在BFS中要始终把握的一个关键是“每个节点只入队一次”,故一定要注意设置的inqueue数组是用来标记其是否入过队而不是是否被访问过,也即当其入队后即将标志修改为true而不是出队后再进行修改
(2)我认为这道题是对BFS非常典型的应用。与矩阵结合考察,那么为了方便入队可以设置struct结构体来存储节点坐标。但注意只是在入队时再为节点赋值即可,其它辅助数组中依然直接用坐标操作(开始时我以为在主函数输入后就要用节点存储起来 导致结构非常乱)。
(3)另外,对于一些求最小步数的题目也很适合用BFS来做。因为BFS是通过层次的顺序来遍历,因此可以从起点S开始计算遍历的层数,当到达一个终点时就是需要求解的最小步数。

在这里插入图片描述
参照了《算法笔记》的一些思路又结合了自己的理解。
我觉得书中对一个节点周围相邻节点遍历时,使用三个数组

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 };
for (int i = 0; i < 6; i++)
			int newX = temp.x + X[i], newY = temp.y + Y[i], newZ = temp.z + Z[i];

的方法非常值得借鉴。

int m, n, l, t;
int rec[1300][130][70] = { 0 };  //记录各坐标在立方体中的序号
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 };
bool visited[1300][130][70]= { false };
struct cNode
{
	int x;
	int y;
	int z;
}cube[1010];
queue<cNode> q;
//判断某一节点是否超出了立方体范围
bool judge(int x, int y, int z)
{
	if (x >= 0 && x < m&&y>=0 && y < n&&z>=0 && z < l)
		return true;
	else
		return false;
}
void BFS(cNode cn,int &sum)
{
	q.push(cn);
	visited[cn.x][cn.y][cn.z] = true;
	while (!q.empty())
	{
		cNode temp = q.front();
		q.pop();
		sum += 1;
		//遍历其相邻元素
		for (int i = 0; i < 6; i++)
		{
			int newX = temp.x + X[i], newY = temp.y + Y[i], newZ = temp.z + Z[i];
			if (judge(newX,newY,newZ))
			{
				if (rec[newX][newY][newZ] == 1 && visited[newX][newY][newZ] == false)
				{
					cNode newC;
					newC.x = newX;
					newC.y = newY;
					newC.z = newZ;
					visited[newX][newY][newZ] = true;
					q.push(newC);
				}
			}
		}
	}
}



int main()
{
	scanf("%d %d %d %d", &m, &n, &l, &t);
	int count = 0;
	for (int i = 0; i < l; i++)
		for (int j = 0; j < m; j++)
			for (int k = 0; k < n; k++) {
				scanf("%d", &rec[j][k][i]);
			}
	int res = 0;
	//遍历立方体
	for (int i = 0; i < l; i++)
		for (int j = 0; j < m; j++)
			for (int k = 0; k < n; k++)
			{
				int sum = 0;
				cNode newC;
				//某节点还未被访问
				if (visited[j][k][i] == false && rec[j][k][i]== 1) {
					newC.x = j, newC.y = k, newC.z = i;
					BFS(newC, sum);
				}
				if (sum >= t)
					res += sum;
			}
	cout << res;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值