您的位置:首页 > 其它

BFS解迷宫问题,并打印最短路径

2016-02-03 16:48 471 查看
第一行两个整数n, m,为迷宫的长宽。

  接下来n行,每行m个数,数之间没有间隔,为0或1中的一个。0表示这个格子可以通过,1表示不可以。假设你现在已经在迷宫坐标(1,1)的地方,即左上角,迷宫的出口在(n,m)。每次移动时只能向上下左右4个方向移动到另外一个可以通过的格子里,每次移动算一步。数据保证(1,1),(n,m)可以通过。

输出格式

  第一行一个数为需要的最少步数K。

  第二行K个字符,每个字符∈{U,D,L,R},分别表示上下左右。如果有多条长度相同的最短路径,选择在此表示方法下字典序最小的一个。

样例输入

Input Sample 1:

3 3

001

100

110

Input Sample 2:

3 3

000

000

000

样例输出

Output Sample 1:

4

RDRD

Output Sample 2:

4

DDRR

#include<iostream>
#include<queue>
#include<string>
using namespace std;

struct Node
{
int x;			//坐标x
int y;			//坐标y
Node *P;		//存储前一节点地址
char d;		//移动方向
};
typedef Node direct;
const direct D[4] = { { 1, 0 },{ 0, 1 },{ -1, 0 },{ 0, -1 } };	//下右上左
const char Dir[4] = { 'D','R','U','L' };		//方向
//全局变量
int n, m;	//迷宫长和宽
int **pic;	//迷宫图	1为边界
int **visit;	//0表示为访问 1表示已访问
Node **Parent;		//存储每一个结点
string short_path = "";	//最短路径

void input()	//输入函数
{
cin >> n >> m;
pic = new int*[n + 2];		//迷宫数组
visit = new int*[n + 2];//访问数组
Parent = new Node*[n + 2];
//P_Node = new Node*[n + 2];	//结点数组
for (int i = 0; i < n + 2; i++)
{
pic[i] = new int[m + 2];
visit[i] = new int[m + 2];
Parent[i] = new Node[m + 2];
}

//迷宫初始化,访问数组初始化
for (int i = 0; i < n + 2; i++)
for (int j = 0; j < m + 2; j++)
{
pic[i][j] = 1;
visit[i][j] = 0;
}
char temp;
for (int i = 1; i <= n; i++)		//数据输入,在迷宫中心输入,保留迷宫外墙
for (int j = 1; j <= m; j++)
{
if ((temp = getchar()) != '\n')
pic[i][j] = temp - '0';
else
j--;
}

}

bool check(int x, int y)		//检验坐标合法性
{
if (visit[x][y] || pic[x][y])	//如果该点已被访问 或该点为1(障碍)
return false;	//不合法
return true;
}
string Get_path()		//获得路径和总步数
{
int step = 0;		//步数
string path = "";	//路径
Node *Par;
path = Parent
[m].d + path;	//获取终点方向
Par = Parent
[m].P;	//获取终点的父指针
for (;;)		//循环找每个结点的父节点
{
step++;	//每次循环代表回退一步
path = Par->d + path;	//从终点向起点遍历父节点,所以方向符号放到字符串末尾
if (Par->x == 1 && Par->y == 1) break;	//如果父节点为起点退出
Par = Par->P;	//获取该结点的父节点
}
path[0] = step + '0';		//第一位保存路径长度
return path;
}
void BFS()
{
queue<Node> Q;	//定义队列
Node start = { 1, 1, NULL,'S' };		//起点
Node end = { n, m };	//终点
Node now, next;	//记录当前和下一步
visit[start.x][start.y] = 1;	//访问数组状态改变
Q.push(start);	//起点入队
while (!Q.empty())	//队列非空
{
now = Q.front();	//队首出队
Parent[now.x][now.y] = now;	//当前结点存入数组
Q.pop();	//删除队首
if (now.x == end.x&&now.y == end.y)	//如果到达终点则找到路径
{
if (short_path == "")	//如果为第一条路径
short_path = Get_path();		//获取路径存入全局变量
else
short_path = (Get_path() < short_path) ? Get_path() : short_path;
//比较选择步数少的路径,如果相同则选取方向按字典序排列较小的
}
for (int i = 0; i < 4; i++)
{
//获取下一步动作
next.x = now.x + D[i].x;
next.y = now.y + D[i].y;
next.P = &Parent[now.x][now.y];	//父指针指向当前地址
if (check(next.x, next.y))		//如果下一步合法
{
visit[next.x][next.y] = 1;
next.d = Dir[i];		//存储移动方向
Q.push(next);		//入队
}
}
}
}

int main()
{
input();	//输入
BFS();
int step = short_path[0] - '0';	//获取步数
short_path = short_path.substr(1, short_path.length() - 1);	//获取路径
cout << step << endl;	//输出步数
cout << short_path << endl;		//输出路径
for (int i = 0; i < n; i++)
{
delete[]pic[i];
delete[]visit[i];
delete[]Parent[i];
}
delete[]pic;
delete[]visit;
delete[]Parent;
return 0;
}


但是好像还是有问题实在找不到了

求大神指点
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: