POJ 2984 迷宫问题(搜索 路径的还原)

来源:互联网 发布:橡皮网组卷 源码 编辑:程序博客网 时间:2024/04/29 02:30


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



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 00 1 0 1 00 0 0 0 00 1 1 1 00 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 写,Mzx 说可以用dfs写,并且记录路径的方式还简单,我想了一下,用dfs 确实简单了很多,今天我就先贴出bfs代码,有时间再写个 dfs 代码粘出来,我这个写的复杂了,本来简单的问题被我写的复杂了好多,唉,本事不到家啊!差的太远


附上代码1:(bfs)

#include <iostream>#include <algorithm>#include <string>#include <cstdio>#include <cstring>#include <queue>using namespace std;int d[4][2] = {1,0,-1,0,0,1,0,-1},visit[10][10];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,};struct A{int x,y,step;int a[50],b[50];};void bfs(int x1,int y1,int x2,int y2){int s,t;queue<A> Q;A e;e.x = x1;e.y = y1;e.step = 0;e.a[e.step] = e.x;e.b[e.step] = e.y;Q.push(e);visit[x1][y1] = 1;while(!Q.empty()){e = Q.front();if(e.x == x2 && e.y == y2){for(int i = 0;i <= e.step;i++){printf("(%d, %d)\n",e.a[i],e.b[i]);}return;}Q.pop();for(int i = 0;i < 4;i++){s = e.x + d[i][0];t = e.y + d[i][1];if(s >= 0 && s < 5 && t >= 0 && t < 5 && visit[s][t] == 0 && maze[s][t] == 0){A e1;e1.x = s;e1.y = t;for(int j = 0;j <= e.step;j++){e1.a[j] = e.a[j];e1.b[j] = e.b[j];}e1.step = e.step + 1;e1.a[e1.step] = s;e1.b[e1.step] = t;Q.push(e1);visit[s][t] = 1;}}}}int main(){memset(visit,0,sizeof(visit));bfs(0,0,4,4);return 0;}



附上代码2:(bfs)

#include <iostream>#include <cstring>#include <algorithm>#include <queue>#include <stack>#include <cstdio>using namespace std;int Map[10][10];int dt[4][2] = {0,1,1,0,0,-1,-1,0};struct point{int x,y;int stop;};struct path{int prev_x,prev_y;   // 该坐标的上一个坐标,也就是记录他是从哪一个坐标走过来的int New_x,New_y;    //  当前点的坐标};void bfs(int cur,int let,int st){path P_pa;         //  定义结构体,这点我这个代码里用的很糟,这点用了 大写 P 下面还有一个定义成 小写 p 大家注意点吧queue<point> Q;stack<path> p_path;P_pa.prev_x = -1;P_pa.prev_y = -1;P_pa.New_x = cur;P_pa.New_y = let;point q;Map[cur][let] = 1;q.x = cur;q.y = let;q.stop = st;Q.push(q);while(!Q.empty()){q = Q.front();Q.pop();if(q.x == 4 && q.y == 4)break;for(int i = 0;i < 4;i++){int tx = q.x + dt[i][0];int ty = q.y + dt[i][1];if(tx >= 0 && tx < 5 && ty >= 0 && ty < 5 && !Map[tx][ty]){point qq;qq.stop = q.stop + 1;qq.x = tx;qq.y = ty;Q.push(qq);Map[tx][ty] = 1;P_pa.prev_x = q.x;P_pa.prev_y = q.y;P_pa.New_x = tx;P_pa.New_y = ty;p_path.push(P_pa);}}}while(!Q.empty())Q.pop();P_pa.prev_x = -1;P_pa.prev_y = -1;path p_pa;             // 定义的小写 pstack<point> ans;while(!p_path.empty())     //  从路径的记录中找到真正的那条路径{p_pa = p_path.top();p_path.pop();if(p_pa.New_x == 4 && p_pa.New_y == 4){P_pa = p_pa;} if(p_pa.New_x == P_pa.prev_x && p_pa.New_y == P_pa.prev_y)   //  找到该坐标的上一个坐标,就进行赋值,修改当前坐标,继续寻找上一个坐标 { point an; an.x = p_pa.New_x; an.y = p_pa.New_y; P_pa = p_pa; ans.push(an);       // 找到一个路径中的坐标,压入 ans 栈中 }}printf("(0, 0)\n");   //  在上面路径的寻找过程中 起始点和终止点是没有,储存的  所以直接输出,终止点下面输出while(!ans.empty())        //  依次访问 ans 栈,输出中间的路径{point an;an = ans.top();ans.pop();printf("(%d, %d)\n",an.x,an.y);}printf("(4, 4)\n");          //  输出终止点}int main(){memset(Map,0,sizeof(Map)); for(int i = 0;i < 5;i++) { for(int j = 0;j < 5;j++) { cin >> Map[i][j];} } bfs(0,0,0); return 0;}





0 0
原创粉丝点击