一个迷宫由一个0/1矩阵表示,每个单元格要么是空地0,要么是障碍物1,找到入口到出口的最短距离,任何时候 不能在障碍物中,也不能出迷宫。只能横着走,竖着走, 输入:(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 输出:(路径) (0,0) (1,0) (2,0) (2,1) (2,2) (2,3) (2.4) (3.4) (4,4)
网上看到的一个类似代码:
#include <cstdio> #include <iostream> #include <queue> using namespace std; const int MAX_N = 100; const int MAX_M = 100; const int INF = 0x3f3f3f3f; typedef pair<int, int> P; char maze[MAX_N][MAX_M + 1]; int N, M; int sx, sy; //起点的位置 int gx, gy; //终点的位置 int d[MAX_N][MAX_M];//储存起点到某一点的距离 int dx[4] = { 1,0,-1,0 }, dy[4] = { 0,1,0,-1 }; //表明每次x和y方向的位移 void bfs() { queue<P> que; for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) d[i][j] = INF; //初始化所有点的距离为INF que.push(P(sx, sy)); d[sx][sy] = 0; //从起点出发将距离设为0,并放入队列首端 while (que.size()) //题目保证有路到终点,所以不用担心死循环 { P p = que.front(); que.pop();//弹出队首元素 if(p.first == gx&&p.second == gy) break; //已经到达终点则退出 for (int i = 0; i < 4; i++) { int nx = p.first + dx[i]; int ny = p.second + dy[i];//移动后的坐标 //判断可移动且没到过 if (0 <= nx&&nx < N && 0 <= ny&&ny < M &&maze[nx][ny] != '#' &&d[nx][ny] == INF)//之前到过的话不用考虑,因为距离在队列中递增,肯定不会获得更好的解 { que.push(P(nx, ny)); //可以移动则设定距离为之前加一,放入队列 d[nx][ny] = d[p.first][p.second] + 1; } } } } int main() { scanf("%d %d",&N,&M); for (int n = 0; n < N; n++) scanf("%s",&maze[n]); for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) { if (maze[i][j] == 'S') { sx = i; sy = j; } if (maze[i][j] == 'G') { gx = i; gy = j; } } bfs(); printf("%d ",d[gx][gy]); return 0; }
阅读代码后开始工作了,,,
可以求出距离但是打印不出来路径
//走迷宫问题 #include<iostream> #include<queue> using namespace std; int G[50][50]; int d[50][50]; const int inf=0x3f3f3f3f; typedef pair<int,int > p; int n,i,j; int sx=0,sy=0; int gx=4,gy=4; int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1}; void bfs(){ queue<p> que; for(i=0;i<n;i++) for(j=0;j<n;j++) d[i][j]=inf; que.push(p(sx,sy)); d[sx][sy]=0; while(que.size()){ p pm=que.front(); que.pop(); if(pm.first==gx&&pm.second==gy) break; for(i=0;i<4;i++){ int nx=pm.first+dx[i]; int ny=pm.second+dy[i]; if(nx>=0&&nx<n&&ny>=0&&ny<n&&G[nx][ny]!=1){ que.push(p(nx,ny)); d[nx][ny]=d[pm.first][pm.second]+1; } } } } int main() { int i,j; while(cin>>n){ for ( i = 0; i < n; i++) for ( j = 0; j < n; j++) d[i][j] = inf; //初始化所有点的距离为INF for(i=0;i<n;i++){ for(j=0;j<n;j++) cin>>G[i][j]; } //cout<<"hello"<<endl; bfs(); cout<<d[gx][gy]<<endl; for(i=0;i<n;i++){ for(j=0;j<n;j++) if(d[i][j]<inf) cout<<"0"<<" "; else cout<<"x"<<" "; cout<<endl; } } }
最终复习代码:
//走迷宫 #include<iostream> using namespace std; const int maxn=5; int i,j,tx,ty; int g[5][5]={0}; int vis[5][5]={0}; typedef struct node{ int x,y,f,d; }node; int dx[4]={-1,1,0,0}; int dy[4]={0,0,-1,1}; node que[maxn*maxn]; int head=0,tail=1; void print(int n){ if(que[n].f!=-1){ print(que[n].f); printf("(%d,%d) ",que[n].x,que[n].y); printf("当时的距离为: %d ",que[n].d); // print(que[n].f); } else { printf("(%d,%d) ",que[n].x,que[n].y); printf("当时的距离为: %d ",que[n].d); return ; } } void bfs(){ que[0].x=0; que[0].y=0; que[0].d=0; que[0].f=-1; vis[0][0]=1; while(head<tail){ for(i=0;i<4;i++){ tx=que[head].x+dx[i]; ty=que[head].y+dy[i]; if(tx>=0&&tx<maxn&&ty>=0&&ty<maxn&&!vis[tx][ty]&&!g[tx][ty]){ vis[tx][ty]=1; que[tail].x=tx; que[tail].y=ty; que[tail].d=que[head].d+1; que[tail].f=head; if(tx==4&&ty==4) { print(tail); cout<<"hello,worlf"<<endl; return; } tail++; } } head++; } } int main() { for(i=0;i<maxn;i++){ for(j=0;j<maxn;j++) cin>>g[i][j]; } for(i=0;i<maxn;i++){ for(j=0;j<maxn;j++) cout<<g[i][j]; cout<<endl; } //cout<<"距离"<<que[tail].d<<endl; bfs(); cout<<"距离"<<que[tail].d<<endl; }
分析:
注意递归调用的不同输出的顺序不同:
void print(int n){ if(que[n].f!=-1){ print(que[n].f); printf("(%d,%d) ",que[n].x,que[n].y); printf("当时的距离为: %d ",que[n].d); // print(que[n].f); } else { printf("(%d,%d) ",que[n].x,que[n].y); printf("当时的距离为: %d ",que[n].d); return ; } }
测试数据:
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