迷宫问题
Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u
Description
定义一个二维数组:
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
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 写,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; // 定义的小写 p
stack<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;
}