Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 22809 | Accepted: 13292 |
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)
这是一道广搜+递归的题,前天做过一个迷宫的最短路的题,看到这个题的时候我觉得我会很快做出来,结果后来递归递了半天,前天做的是只要求最短路的步数,而这个要输出路径来,并且做的那个题是用pair状态做的,对队列掌握的并不深的我,有点懵逼,通过这个题,对队列了解的深了点!
用rear尾指针指向下一个,front指向头元素,就相当于我用rear这样一路记录下去,而遇到分岔路口的时候,front就起作用了,它可以先去标记一个支点,标记完了以后再去标记另一个支点,以此类推,保证不一路搜到底,而是横着搜,只可意会,不可言传啊,自己懂,但是讲不清楚
二、用vector、pair做#include<iostream> using namespace std; struct Node{ int x; int y; int pre; }queue[50];//建立一个50个格子的队列; int a[5][5];//迷宫的地图 int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};//控制移动方向的数组 int vis[5][5];//标记 int front=0;//队头 int rear=0;//队尾 头指针指向头元素,尾指针指向队尾的下一个位置 void print(Node now)//输出 { int t=now.pre; if(t==-1) { cout<<"("<<now.x<<", "<<now.y<<")"<<endl; } else { print(queue[now.pre]); cout<<"("<<now.x<<", "<<now.y<<")"<<endl; } } //广搜 void bfs(int sx,int sy,int gx,int gy) { queue[0].x=sx; queue[0].y=sy;//起点的坐标 queue[0].pre=-1;//将初始结点[0,0]压入队列 rear=rear+1; vis[0][0]=1; while(front<rear)//如果队列不为空 { for(int i=0;i<5;i++)//搜索方向 { int nx=queue[front].x+dx[i]; int ny=queue[front].y+dy[i]; if(nx>=0&&nx<5&&ny>=0&&ny<5&&vis[nx][ny]!=1&&a[nx][ny]!=1)//判断是否在地图里,是否被标记,是否撞墙 { queue[rear].x=nx; queue[rear].y=ny; queue[rear].pre=front; vis[nx][ny]=1; rear++; if(nx==4&&ny==4) return ; } } front++; } } int main() { for(int i=0;i<5;i++) { for(int j=0;j<5;j++) { cin>>a[i][j]; } } bfs(0,0,4,4); print(queue[rear-1]); return 0; }
#include <cstdio> #include "stdlib.h" #include "iostream" #include "algorithm" #include "string" #include "cstring" #include "queue" #include "cmath" #include <vector> #include "map" #include "set" #define mj #define db double #define ll long long using namespace std; const int N=1e8+2; const int mod=1e9+7; const ll inf=1e16+10; typedef pair<int,int> P; vector<P> m; queue<P> q; P fa[12][12]; int s[12][12]; int d[12][12]; int dx[4]= {1,0,-1,0},dy[4]= {0,1,0,-1}; void pt(P u) { while(1) { m.push_back(u);//从后往前找父节点 if(u==P(0,0)) break;//根节点 u=fa[u.first][u.second]; } for(int i=(int)m.size()-1; i>=0; i--) //从根节点开始依次输出路径 printf("(%d, %d)\n",m[i].first,m[i].second); } void bfs() { for(int i=0; i<5; i++) { for(int j=0; j<5; j++) { d[i][j]=N; } } q.push(P(0,0)); d[0][0]=0; while(q.size()) { P p; p=q.front(),q.pop(); if(p.first==4&&p.second==4) { pt(p); return; } for(int i=0; i<4; i++) { int nx=p.first+dx[i],ny=p.second+dy[i]; if(0<=nx&&nx<5&&0<=ny&&ny<5&&!s[nx][ny]&&d[nx][ny]==N) { d[nx][ny]=d[p.first][p.second]+1; fa[nx][ny]=p; q.push(P(nx,ny)); } } } } int main() { memset(s,-1, sizeof(s)); for(int i=0; i<5; i++) { for(int j=0; j<5; j++) { scanf("%d",&s[i][j]); } } bfs(); return 0; }