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
但是好像还是有问题实在找不到了
求大神指点
接下来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; }
但是好像还是有问题实在找不到了
求大神指点
相关文章推荐
- 信贷管理
- [剑指offer-1510]替换空格
- Asp.Net MVC过滤器小试牛刀
- ios 类似安卓提示框自动消失
- 【Linux Shell脚本攻略之一】find命令:文件查找和文件列表
- SaaS模式实现架构实例分析=数据库层的设计
- IT 服务管理工具 iTop
- Android关于Fragment长期置于后台返回重叠的问题
- SQL Server 诊断查询-(3)
- 在Eclipse中配置Web服务器,并开发部署一个简单的web应用
- Failed to initialize NVML: GPU access blocked by the operating system
- 模板引擎FreeMarker【整理2】
- HDU 4725 The Shortest Path in Nya Graph(堆优化dijkstra)
- jsp中使用EL表达式的简写方式
- selector的使用
- 《数据库索引设计优化》读书笔记(五)
- 如何在JS判断是否为IE浏览器
- c语言一些经典语句 【精华】
- 论坛开发总结
- (7)UI(基础对象)