迷宫问题
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 14568 | Accepted: 8711 |
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找到的是最短路,且每一个点只能被访问一次,因此回溯的时候一定是一条最短的路。本来想用另一种方法用下标回溯状态,但是发现每一种状态展开后会叠在前一种后面,需要好几个辅助容器,比较麻烦。还是用一般方法
代码:
#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) ",t.x,t.y); ans.pop(); } return 0; }