poj 2251(BFS)

这道题是典型的广度搜索的案例啊。

http://poj.org/problem?id=2251

题目的大意就是,在一个多层次的空间内,要寻找由入口到出口的最短路径。

开始时我想用DFS来完成的,但是DFS经过深搜过后得到的值不一定为最短路径。而有可能要进过回溯迭代才能得到最优解。所以使用DFS会损失大量的时间。

这一题,我们要使用的是BFS。何为BFS,就是对所经过的点进行尽可能广度的搜索,并标记。在这一题中我使用了队列来对所得到的结果进行优化。那么当我们第一次找到终点的时候,此时的时间一定为最优解。这样做,对比深度优先思想来说,具有很大的优势。

同时我采用了将字符迷宫改为数字迷宫,并记录了起点的坐标。另外还要注意的是x,y,z和i,j,k的关系。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
int map[32][32][32], leval_num, row_num, col_num,ans;
bool visited[32][32][32];
int map_t[32][32][32];
int move_a[6][3] = { { 0, 0, 1 }, { 0, 0, -1 }, { 1, 0, 0 }, { -1, 0, 0 }, { 0, 1, 0 }, {0,-1,0} };
bool flag;
struct node
{
	int x, y, z;
}st_point;
queue<node>qs;
bool judge(int x, int y, int z,int time)
{
	if (z <= 0 || z > leval_num)return false;
	else if (x <= 0 || x > col_num)return false;
	else if (y <= 0 || y > row_num)return false;
	else if (map[z][y][x] == 2)return false;
	else if (time > map_t[z][y][x])return false;
	else if (visited[z][y][x])return false;
	return true;
}//判断该点是否有效
void bfs(int x, int y, int z, int time)
{
	int i,tempx,tempy,tempz;
	node movement;
	if (flag)return;
	if (map[z][y][x] == 3)
	{
		ans = time;
		flag = true;
		return;
	}//如果达到了终点,就进行返回
	for (i = 0; i < 6; i++)
	{
		tempx = x + move_a[i][0];
		tempy = y + move_a[i][1];
		tempz = z + move_a[i][2];
		bool temp = judge(tempx, tempy, tempz, time + 1);
		if (temp)
		{
			map_t[tempz][tempy][tempx] = time +1;
			visited[tempz][tempy][tempx] = true;
			movement.x = tempx;
			movement.y = tempy;
			movement.z = tempz;
			qs.push(movement);
		}
	}//对目标点进行广度搜索
	if (qs.empty())return;
	x = qs.front().x; y = qs.front().y; z = qs.front().z;
	qs.pop();
	bfs(x,y,z, map_t[z][y][x]);
	return;
}
int main()
{
	int i, j, k;
	char temp_c;
	while (scanf_s("%d %d %d", &leval_num, &row_num, &col_num) != EOF)
	{
		memset(map_t, INF, sizeof(map_t));
		memset(visited, false, sizeof(visited));
		flag = false;
		ans = INF;
		if (!leval_num && !row_num && !col_num)break;
		for (i = 1; i <= leval_num; i++)
		{
			for (j = 1; j <= row_num; j++)
			{
				for (k = 1; k <= col_num; k++)
				{
					cin >> temp_c;
					if (temp_c == '.')map[i][j][k] = 1;
					else if (temp_c == '#')map[i][j][k] = 2;
					else if (temp_c == 'S')
					{
						st_point.z = i;
						st_point.x = k;
						st_point.y = j;
						map[i][j][k] = 1;
					}
					else if (temp_c == 'E')map[i][j][k] = 3;
				}
				getchar();
			}
		}//输入时对迷宫进行优化
		map_t[st_point.z][st_point.y][st_point.x] = 0;
		visited[st_point.z][st_point.y][st_point.x] = true;
		bfs(st_point.x, st_point.y, st_point.z, 0);

		if (!flag)cout << "Trapped!" << endl;
		else cout << "Escaped in " << ans << " minute(s)." << endl;
		if (!qs.empty())qs.pop();//结束后清空队列
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值