迷宫问题
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 14568   Accepted: 8711

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)

这题的状态记录和上一题的不太一样,上一题是不需要回溯的,这题需要回溯,因此不再是简单地记录上一个节点的状态,而是每一个点都记录前驱点,这样根据终点可以回溯到起点。显然每一个点可以向四个方向拓展,因此一个点最多可以成为四个拓展点的前驱点,但这不意味着一个点同时存在四种状态,而是四种状态被分开来压入队列。以前在这点上一直搞不清楚,这题就不会做。由于BFS找到的是最短路,且每一个点只能被访问一次,因此回溯的时候一定是一条最短的路。本来想用另一种方法用下标回溯状态,但是发现每一种状态展开后会叠在前一种后面,需要好几个辅助容器,比较麻烦。还是用一般方法

代码:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
#define MMINF(x) memset(x,INF,sizeof(x))
typedef long long LL;
const double PI=acos(-1.0);
struct info
{
int x;
int y;
int prex;
int prey;
};
info direct[4]={{0,1},{0,-1},{1,0},{-1,0}};
info operator+(const info &a,const info &b)
{
info c;
c.x=a.x+b.x;
c.y=a.y+b.y;
return c;
}
int pos[5][5],vis[5][5];
info history[5][5]={{0,0,-1,-1}};
inline bool check(const info &a)
{
if((!vis[a.x][a.y])&&(!pos[a.x][a.y])&&(a.x>=0&&a.y>=0&&a.x<5&&a.y<5))
return true;
return false;
}
int main(void)
{
int i,j;
for (i=0; i<5; i++)
{
for (j=0; j<5; j++)
{
scanf("%d",&pos[i][j]);
}
}
queue<info>Q;
Q.push(history[0][0]);
vis[history[0][0].x][history[0][0].y]=1;
while (!Q.empty())
{
info now=Q.front();
Q.pop();
for (int i=0; i<4; i++)
{
info v=now+direct[i];
v.prex=now.x;
v.prey=now.y;
if(check(v))
{
Q.push(v);
vis[v.x][v.y]=1;
history[v.x][v.y]=v;
}
}
if(now.x==4&&now.y==4)
break;
}
stack<info>ans;
info k=history[4][4];
puts("(0, 0)");
while (k.prex!=-1)
{
ans.push(k);
k=history[k.prex][k.prey];
}
while (!ans.empty())
{
info t=ans.top();
printf("(%d, %d)\n",t.x,t.y);
ans.pop();
}
return 0;
}

POJ——3984迷宫问题(BFS+回溯)的更多相关文章

  1. POJ 3984 - 迷宫问题 - [BFS水题]

    题目链接:http://poj.org/problem?id=3984 Description 定义一个二维数组: int maze[5][5] = { 0, 1, 0, 0, 0, 0, 1, 0, ...

  2. POJ 3984 迷宫问题 bfs 难度:0

    http://poj.org/problem?id=3984 典型的迷宫问题,记录最快到达某个点的是哪个点即可 #include <cstdio> #include <cstring ...

  3. [POJ 3984] 迷宫问题(BFS最短路径的记录和打印问题)

    题目链接:http://poj.org/problem?id=3984 宽度优先搜索最短路径的记录和打印问题 #include<iostream> #include<queue> ...

  4. POJ - 3984 迷宫问题 BFS求具体路径坐标

    迷宫问题 定义一个二维数组: 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, ...

  5. poj 3984 迷宫问题 bfs

    学会这道水题之后我懂得了不少哈,首先水题也能学到不少知识,尤其像我这样刚入门的小菜鸟,能学到一些小技巧. 然后就是可以从别人的代码里学到不一样的思路和想法. 这题就是求最短的路径,首先想到就是用bfs ...

  6. POJ - 3984 迷宫问题 bfs解法

    #include<stdio.h> #include<string.h> #include<algorithm> #include<stack> usi ...

  7. POJ 3984 迷宫问题 (BFS + Stack)

    链接 : Here! 思路 : BFS一下, 然后记录下每个孩子的父亲用于找到一条路径, 因为寻找这条路径只能从后向前找, 这符合栈的特点, 因此在输出路径的时候先把目标节点压入栈中, 然后不断的向前 ...

  8. BFS(最短路+路径打印) POJ 3984 迷宫问题

    题目传送门 /* BFS:额,这题的数据范围太小了.但是重点是最短路的求法和输出路径的写法. dir数组记录是当前点的上一个点是从哪个方向过来的,搜索+,那么回溯- */ /************* ...

  9. POJ 3984 迷宫问题(简单bfs+路径打印)

    传送门: http://poj.org/problem?id=3984 迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions ...

  10. POJ 3984 迷宫问题

    K - 迷宫问题 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Sta ...

随机推荐

  1. 修改完linux bashrc文件之后,如何不重启系统使其生效

    修改完后,输入如下命令即可 ##@##:~/    source ~/.bashrc 之后bashrc文件就可以使用! 注: 使用ssh登陆shell的时候,系统不会自动调用.bashrc文件, 只是 ...

  2. SQLServer同一实例下事务操作

    参考代码: 引用Dapper public bool OrderAdd2(User user, Order order) { string dbString = ConfigurationManage ...

  3. Android学习总结(八)———— 广播的最佳实践(实现强制下线功能)

    一.基本概念 强制下线功能功能应该算是比较常见的了,很多应用程序都具备这个功能,比如你的QQ号或者微信号在别处登录了,就会将你强制挤下线.只需要在界面上弹出一个对话框,让用户无法进行任何其他的操作,必 ...

  4. Scalatra

    SBT和giter8 在你开始着手之前,你需要安装两个工具(我假设你已经安装了JDK1.6+).我将给你提供简缩的安装指令,详细版的安装指令可通过 下面的scalatra页面找到( http://ww ...

  5. SSave ALAsset image to disk fast on iOS

    I am using ALAsset to retrieve images like that: [[asset defaultRepresentation] fullResolutionImage] ...

  6. var、let、const声明变量的区别

    let和var声明变量的区别:1.let所声明的变量只在let命令所在的代码块内有效.(块级作用域) for(let i=0;i<10;i++){ // ... } console.log(i) ...

  7. KeyValuePair的使用

    Dictionary<string, string> dc = new Dictionary<string, string>(); 前台页面: <div id=" ...

  8. msys2 使用指定boost

    pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-openssl mingw-w64- ...

  9. hibernate3缓存(hibernate)

    一级缓存:当应用程序调用Session 的save() .update() .savaeOrUpdate() .get() 或load() ,以及调用查询接口的list() .iterate() 或f ...

  10. shell脚本,计算学生分数的题目。

    1.计算学生平均分数的值是多少? 2.计算每门课都大于80分的学生姓名.3.计算每门课都小于90分的学生姓名.