迷宫问题 POJ - 3984
定义一个二维数组:
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被坑的错误代码】
/*
这个代码坑了我的点:
1.print_path函数坑我的点已经注释
2.最坑的地方是我记录路径的方法,我用next数组来记录路径,
仔细想想,用脑走一下bfs就知道next是不对的,比如下面这个:
0 1 1 1 1
0 1 1 1 1
0 0 1 1 1
0 1 1 1 1
0 0 0 0 0
如果进队顺序是(0,0),(1,0),(2,0),(3,0),(2,1)这样的话,由
原来的next[2][0].x=3,next[2][0].y=0变成了next[2][0].x=2,
next[2][0].y=1,接着继续进队的是(3,0),但是(2,0)和(3,0)
已经失去了联系。所以还是用pre数组来记录路径是没问题的,
这里就是一对多改成了多对一,多对一是完全正确的,好似函数
的概念乎!
上面的第2个坑点导致了死循环的出现。(next数组是全局的,
其所有值默认为0)
*/
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int a[10][10];
bool vis[10][10];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
typedef struct{
int x,y;
}point;
point next[10][10];
void input();
void bfs();
void print_path();
int main()
{
input();
bfs();
print_path();
return 0;
}
void input(){
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
cin>>a[i][j];
}
void bfs(){
memset(vis,0,sizeof(vis));
point p,q;
p.x=p.y=0;
queue<point>que;
que.push(p);
vis[p.x][p.y]=1;
while(!que.empty()){
if(p.x==4 && p.y==4) break;
p=que.front();
que.pop();
int xx,yy;
for(int i=0;i<4;i++){
xx=p.x+dir[i][0];
yy=p.y+dir[i][1];
if(xx>=0 && xx<=4 && yy>=0 && yy<=4 && !a[xx][yy] && !vis[xx][yy]){
q.x=xx;
q.y=yy;
que.push(q);
vis[xx][yy]=1;
next[p.x][p.y].x=xx;
next[p.x][p.y].y=yy;
}
}
}
}
void print_path(){
int x=0,y=0;
while(!(x==4 && y==4)){
cout<<"("<<x<<", "<<y<<")"<<endl;
/*
坑我的点:
下面这么写的话,上一个x改变后,影响了下一个式子中的x,导致错误
x=next[x][y].x;
y=next[x][y].y;
*/
int xx=next[x][y].x;
int yy=next[x][y].y;
x=xx;
y=yy;
}
}
【BFS,ac代码】
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
int a[10][10];
bool vis[10][10];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
typedef struct{
int x,y;
}point;
point pre[10][10];
void input();
void bfs();
void print_path();
int main()
{
input();
bfs();
print_path();
return 0;
}
void input(){
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
cin>>a[i][j];
}
void bfs(){
memset(vis,0,sizeof(vis));
point p,q;
p.x=p.y=4;
queue<point>que;
que.push(p);
vis[p.x][p.y]=1;
while(!que.empty()){
if(p.x==0 && p.y==0) break;
p=que.front();
que.pop();
int xx,yy;
for(int i=0;i<4;i++){
xx=p.x+dir[i][0];
yy=p.y+dir[i][1];
if(xx>=0 && xx<=4 && yy>=0 && yy<=4 && !a[xx][yy] && !vis[xx][yy]){
q.x=xx;
q.y=yy;
que.push(q);
vis[xx][yy]=1;
pre[xx][yy].x=p.x;
pre[xx][yy].y=p.y;
}
}
}
}
void print_path(){
int x=0,y=0;
while(!(x==4 && y==4)){
cout<<"("<<x<<", "<<y<<")"<<endl;
int xx=pre[x][y].x;
int yy=pre[x][y].y;
x=xx;
y=yy;
}
cout<<"("<<x<<", "<<y<<")"<<endl;
}
【DFS,ac代码】
#include<iostream>
#include<stack>
#include<cstring>
using namespace std;
int mp[10][10];
bool vis[10][10];
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
typedef struct{
int x,y;
}point;
stack<point>sta;
int mmin=1000;
point path[100];
void input();
void dfs(int x,int y,int step);
void update_path(stack<point>sta);
void print_path();
int main()
{
input();
memset(vis,0,sizeof(vis));
dfs(0,0,1);
print_path();
return 0;
}
void input(){
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
cin>>mp[i][j];
}
void dfs(int x,int y,int step){
point p;p.x=x;p.y=y;
sta.push(p);
vis[x][y]=1;
if(x==4 && y==4){
if(step<mmin){
mmin=step;
update_path(sta);
}
}
//下面循环控制深搜结束(四个方向深搜如下)
for(int i=0;i<4;i++){
int xx=x+dir[i][0];
int yy=y+dir[i][1];
if(xx>=0 && xx<=4 && yy>=0 && yy<=4 && !mp[xx][yy] && !vis[xx][yy]){
vis[xx][yy]=1;
dfs(xx,yy,step+1);
vis[xx][yy]=0;//走过的路重新标记为0,可以再次走该点
}
}
sta.pop();//对于某点,四个方向都不能走,就退回上一个点,相应路径点出栈
}
//下面函数中注意要带参数,如果没有参数,直接对全局变量sta操作,是明显错误的
void update_path(stack<point>sta){
for(int i=(int)sta.size();i>=1;i--){
path[i]=sta.top();
sta.pop();
}
}
void print_path(){
for(int i=1;i<=mmin;i++){
cout<<"("<<path[i].x<<", "<<path[i].y<<")"<<endl;
}
}