Description

定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output

左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4) 分析:这道题很明显是一道寻找最短路径的问题,那就应该选择广度优先搜索,首先来说说广搜吧,广搜的基本思想是这样的:
从初始状态S开始,利用规则,生成所有可能的状态。构成树的下一层节点,检查是否出现目标状态G,若未出现,就对该层所有状态节点,分别顺序利用规则。生成再下一层的所有状态节点,对这一层的所有状态节点检查是否出现G,若未出现,继续按上面思想生成再下一层的所有状态节点,这样一层一层往下展开。直到出现目标状态为止。
也就是如下图所示:
我们来看一下维基上的代码:
  std::queue<node*> visited, unvisited;
node nodes[];
node* current; unvisited.push(&nodes[]); //先把root放入unvisited queue while(!unvisited.empty()) //只有unvisited不空
{
current = (unvisited.front()); //目前應該檢驗的 if(current -> left != NULL)
unvisited.push(current -> left); //把左邊放入queue中 if(current -> right != NULL) //右边压入。因为QUEUE是一个先进先出的结构,所以即使后面再压其他东西,依然会先访问这个。
unvisited.push(current -> right); visited.push(current); cout << current -> self << endl; unvisited.pop();
}

首先是有一棵构建好的树,我们从跟节点开始,访问第一层子节点,然后是第二层...这些都应该不难理解。问题是,我们应该怎么初始化这样一棵树,然后怎么记录路径,因为一般给的都只是一个序列,首先你要根据这个序列初始化一棵树然后才能在这棵树的基础上去找。

这里就只考虑迷宫问题吧,首先题目给的是一个二维序列,那么我们就可以直接将这个二维序列看成一棵树,节点就是迷宫路上的每一个格子(非墙),走迷宫的时候,格子间的关系是什么呢?按照题目意思,我们只能横竖走,因此我们可以这样看,格子与它横竖方向上的格子是有连通关系的,只要这个格子跟另一个格子是连通的,那么两个格子节点间就有一条边。如果说本题再修改成斜方向也可以走的话,那么就是格子跟周围8个格子都可以连通,于是一个节点就会有8条边(除了边界的节点)。

下面是记录路径的问题,对于记录路径,我们可以采用回溯法,在每个node里面设一个变量记录它前面的元素,那么在遇到正确结果后就可以以该元素为根往回遍历直到最开始的元素,在每个节点处打印,那这样就把整条路径打印出来了。如:

 struct node{
int pre;
int x;
int y;
} path[]; void print(int i) {//当前节点
if (path[i].pre != -) {//找到前面那个节点
print(path[i].pre);
cout << "(" << path[i].x << "," << path[i].y << ")" << endl;
} else {//最前面的那个节点
cout << "(" << path[i].x << "," << path[i].y << ")" << endl;
}
}

另外一个方法是采用一个stack来专门记录路径,下面我用一个流程来说明:

--》--》...--》--》

--》--》--》...--》--》...--》--》...--》--》

从流程中我们可以看出来了,就不多说了。。。

第三种方法是在node里面设一个list专门记录路径,但是这个方法要记得在每次走到下一个节点的时候将它的父节点的路径记录加上自己的坐标变成自己的路径记录,就像下面这样:

 struct node {
list<int*> path;
int x, y;
node(list<int*> fatherList) {
path = fatherList;
int index[] = {x, y};
path.push_back(index);
}
};

那么在找到最后一个的路径的时候就可以直接打印它的path变量。

有人也许会有疑问,为什么广搜找到的路径就是最短了呢?,看看下面这个图你就明白了:

--》

发现数字的规律了吗?数字是分层的,在同一层的数字所代表的路径长度是相同的,一层层的遍历,当某层第一次到达了出口,这层肯定是最短路径所在层啦。

下面是那道题的代码:

 #include <iostream>

 using namespace std;

 int map[][];

 //相邻四个节点
int borderUponX[] = {, , , -};
int borderUponY[] = {, -, , }; int front = , rear = ; struct node{
int pre;
int x;
int y;
} path[]; void print(int i) {//当前节点
if (path[i].pre != -) {//找到前面那个节点
print(path[i].pre);
cout << "(" << path[i].x << "," << path[i].y << ")" << endl;
} else {//最前面的那个节点
cout << "(" << path[i].x << "," << path[i].y << ")" << endl;
}
} void bfsSearch(int x, int y) {
//开始节点(出发),前面没有节点了
path[front].x = x;
path[front].y = y;
path[front].pre = -; //当front == rear的时候说明已经走完了所以“相邻”节点
//且都不通
while (front < rear) {
for (int i = ; i != ; i++) {
//相邻节点坐标
int pathX = path[front].x + borderUponX[i];
int pathY = path[front].y + borderUponY[i]; //不符合的节点(遇到边界或已经走过了)
if (pathY < || pathX < || pathX > || pathY > || map[pathX][pathY])
continue;
else {//将front的相邻的可以过去的并且是还没有走过的节点加到路径里面
map[pathX][pathY] = ;
path[rear].x = pathX;
path[rear].y = pathY;
path[rear].pre = front;
rear++;
}
if (pathX == && pathY == ) {
//找到了一条路径,又是第一次找到
//那么就是最短路径了
print(rear - );
break;
}
}
front++;
}
} int main(int argc, char const *argv[])
{
for(int i = ;i < ;i++)
for(int j = ;j < ;j++)
cin >> map[i][j]; bfsSearch(,);
return ;
}
												

广度优先搜索--POJ迷宫问题的更多相关文章

  1. POJ 2251 Dungeon Master /UVA 532 Dungeon Master / ZOJ 1940 Dungeon Master(广度优先搜索)

    POJ 2251 Dungeon Master /UVA 532 Dungeon Master / ZOJ 1940 Dungeon Master(广度优先搜索) Description You ar ...

  2. 深度优先搜索(DFS)和广度优先搜索(BFS)求解迷宫问题

    用下面这个简单的迷宫图作为例子: OXXXXXXX OOOOOXXX XOXXOOOX XOXXOXXO XOXXXXXX XOXXOOOX XOOOOXOO XXXXXXXO O为通路,X为障碍物. ...

  3. AOJ 0558 广度优先搜索

    题意:在 H * W 的地图里有 N 个工厂,每个工厂分别生产硬度为1-N 的奶酪,有一只老鼠准备把所有奶酪都吃完.老鼠的初始体力值为1,每吃一个奶酪体力值加 1.已知老鼠不能吃硬度大于当前体力值的奶 ...

  4. 广度优先搜索(BFS)----------------(TjuOj1140_Dungeon Master)

    这次整理了一下广度优先搜索的框架,以后可以拿来直接用了.TjuOj1140是一个三维的迷宫题,在BFS时我增加了一个控制数组,用来对队列的出队进行控制,确保每次出队的结点均为同一步长的结点,个人认为比 ...

  5. 步步为营(十六)搜索(二)BFS 广度优先搜索

    上一篇讲了DFS,那么与之相应的就是BFS.也就是 宽度优先遍历,又称广度优先搜索算法. 首先,让我们回顾一下什么是"深度": 更学术点的说法,能够看做"单位距离下,离起 ...

  6. BFS(三):双向广度优先搜索

    所谓双向广度搜索指的是搜索沿两个方向同时进行:(1)正向搜索:从初始结点向目标结点方向搜索:(2)逆向搜索:从目标结点向初始结点方向搜索:当两个方向的搜索生成同一子结点时终止此搜索过程. 广度双向搜索 ...

  7. 广度优先搜索(Breadth First Search, BFS)

    广度优先搜索(Breadth First Search, BFS) BFS算法实现的一般思路为: // BFS void BFS(int s){ queue<int> q; // 定义一个 ...

  8. 关于宽搜BFS广度优先搜索的那点事

    以前一直知道深搜是一个递归栈,广搜是队列,FIFO先进先出LILO后进后出啥的.DFS是以深度作为第一关键词,即当碰到岔道口时总是先选择其中的一条岔路前进,而不管其他岔路,直到碰到死胡同时才返回岔道口 ...

  9. 算法竞赛——BFS广度优先搜索

    BFS 广度优先搜索:一层一层的搜索(类似于树的层次遍历) BFS基本框架 基本步骤: 初始状态(起点)加到队列里 while(队列不为空) 队头弹出 扩展队头元素(邻接节点入队) 最后队为空,结束 ...

随机推荐

  1. CentOS 访问控制列表(tcp wrappers)

    1.TCP Wrappers是一个工作在应用层的安全工具,它只能针对某些具体的应用或者服务起到一定的防护作用.比如说ssh.telnet.FTP等服务的请求,都会先受到TCP Wrappers的拦截. ...

  2. Oracle 转义字符

    id sfds_V_SF ASD_V_DSAF SD_V_DSAD   下划线是Oracle特殊字符,需要转移,如下    select * from systab t where t.id like ...

  3. [HNOI2009]有趣的数列 卡特兰数

    题面:[HNOI2009]有趣的数列 题解: 观察到题目其实就是要求从长为2n的序列中选n个放在集合a,剩下的放在集合b,使得集合a和集合b中可以一一对应的使a中的元素小于b. 2种想法(实质上是一样 ...

  4. BZOJ4942 & UOJ314:[NOI2017]整数——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4942 http://uoj.ac/problem/314 https://www.luogu.or ...

  5. Git 常用操作(一)

    使用git pull文件时和本地文件冲突: $ git stash $ git pull $ git stash pop stash@{0}   [还原暂存的内容] 上传项目流程: pwd git p ...

  6. mybatis的Mapper代理原理

    前言:在mybatis的使用中,我们会习惯采用XXMapper.java+XXMapper.xml(两个文件的名字必须保持一致)的模式来开发dao层,那么问题来了,在XXMapper的文件里只有接口, ...

  7. 关于javascript数组的定义与其一些常用方法总结

    由于JavaScript是一门宽松的语言,这种宽松可能会带来更加麻烦的事情.比如JavaScript的数组,定义与使用的方式太灵活有时候让人迷惑.下面将JavaScript中关于数组常用的方法.定义之 ...

  8. POJ3974:Palindrome(Manacher模板)

    Palindrome Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 14021   Accepted: 5374 题目链接 ...

  9. 打开cmd窗口新技巧get

    1.在当前目录下,按住shift键+点击右键,选择在此处打开命令窗口 很多时候我们需要打开命令行然后进入到相应目录进行一些操作. 常规的做法是: Win+R打开运行窗口 输入"cmd&quo ...

  10. zabbix调优PPT

    http://www.slideshare.net/xsbr/alexei-vladishev-zabbixperformancetuning# http://zabbixzone.com/zabbi ...