总时间限制: 1000ms
- 内存限制: 65536kB
- 描述
-
当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单。
假设你已经得到了一个n*m的迷宫的图纸,请你找出从起点到出口的最短路。 - 输入
- 第一行是两个整数n和m(1<=n,m<=100),表示迷宫的行数和列数。
接下来n行,每行一个长为m的字符串,表示整个迷宫的布局。字符'.'表示空地,'#'表示墙,'S'表示起点,'T'表示出口。 - 输出
- 输出从起点到出口最少需要走的步数。
- 样例输入
-
3 3 S#T .#. ...
- 样例输出
-
6
分析:
1.深度优先搜索1(过四个点)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c,f[110][110],minc=1000,x0,y0,x1,y1; char a[110][110]; const int d[4][4]={{1,0},{0,1},{-1,0},{0,-1}}; void dfs(int x,int y,int cur){ if(x==x1&&y==y1) { if (cur<minc) minc=cur; return;} for(int i=0;i<=3;i++){ int xx=x+d[i][0],yy=y+d[i][1]; if(a[xx][yy]&&!f[xx][yy]) { f[xx][yy]=1; dfs(xx,yy,cur+1); f[xx][yy]=0; } } } int main(){ cin>>r>>c; char ch; memset(a,0,sizeof(a));//0代表不能通过,这样相当于在外圈加了一圈边界。 memset(f,0,sizeof(f)); for(int i=1;i<=r;i++) for (int j=1;j<=c;j++){ cin>>ch; if (ch=='.') a[i][j]=1; if(ch=='S') {x0=i;y0=j;a[i][j]=1;} if(ch=='T'){x1=i;y1=j;a[i][j]=1;} } f[1][1]=1; dfs(x0,y0,0); cout<<minc<<endl; return 0; }
2.深度优先搜索2(过六个点)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c,f[110][110],minc=1000,x0,y0,x1,y1; char a[110][110]; const int d[4][4]={{1,0},{0,1},{-1,0},{0,-1}}; void dfs(int x,int y,int cur){ if(x==x1&&y==y1) { if (cur<minc) minc=cur; return;} if (cur>=minc)return; for(int i=0;i<=3;i++){ int xx=x+d[i][0],yy=y+d[i][1]; if(a[xx][yy]&&!f[xx][yy]) { f[xx][yy]=1; dfs(xx,yy,cur+1); f[xx][yy]=0; } } } int main(){ cin>>r>>c; char ch; memset(a,0,sizeof(a));//0代表不能通过,这样相当于在外圈加了一圈边界。 memset(f,0,sizeof(f)); for(int i=1;i<=r;i++) for (int j=1;j<=c;j++){ cin>>ch; if (ch=='.') a[i][j]=1; if(ch=='S') {x0=i;y0=j;a[i][j]=1;} if(ch=='T'){x1=i;y1=j;a[i][j]=1;} } f[1][1]=1; dfs(x0,y0,0); cout<<minc<<endl; return 0; }
3.宽度优先搜索1 (使用标志数组f)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c,f[110][110],minc=1000,x0,y0,x1,y1; char a[110][110]; const int d[4][4]={{1,0},{0,1},{-1,0},{0,-1}}; int q[11000][3]; void bfs(){ int head=0,tail=1; q[1][0]=x0;q[1][1]=y0; while (head!=tail){ head++; if (head==r*c+1) head=1; int step=q[head][2]+1; for(int i=0;i<=3;i++){ int x=q[head][0]+d[i][0],y=q[head][1]+d[i][1]; if(a[x][y]&&!f[x][y]) { tail++; if (tail==r*c+1) tail=1; if(x==x1&&y==y1) { minc=q[head][2]+1; return;} q[tail][0]=x; q[tail][1]=y; q[tail][2]=q[head][2]+1; f[x][y]=1; } } } } int main(){ cin>>r>>c; char ch; memset(a,0,sizeof(a));//0代表不能通过,这样相当于在外圈加了一圈边界。 memset(f,0,sizeof(f)); for(int i=1;i<=r;i++) for (int j=1;j<=c;j++){ cin>>ch; if (ch=='.') a[i][j]=1; if(ch=='S') {x0=i;y0=j;a[i][j]=1;} if(ch=='T'){x1=i;y1=j;a[i][j]=1;} } if (x0==x1&&y0==y1) {cout<<0<<endl; return 0;} bfs(); cout<<minc<<endl; return 0; }
4.宽度优先搜索2(去掉标志数组f,直接使用a数组标志)
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c,minc=1000,x0,y0,x1,y1; char a[110][110]; const int d[4][4]={{1,0},{0,1},{-1,0},{0,-1}}; int q[11000][3]; void bfs(){ int head=0,tail=1; q[1][0]=x0;q[1][1]=y0;a[x0][y0]=1; while (head!=tail){ head++; if (head==r*c+1) head=1; for(int i=0;i<=3;i++){ int x=q[head][0]+d[i][0],y=q[head][1]+d[i][1]; if(a[x][y]) { tail++; if (tail==r*c+1) tail=1; if(x==x1&&y==y1) { minc=q[head][2]+1; return;} q[tail][0]=x; q[tail][1]=y; q[tail][2]=q[head][2]+1; a[x][y]=0; } } } } int main(){ cin>>r>>c; char ch; memset(a,0,sizeof(a));//0代表不能通过,这样相当于在外圈加了一圈边界。 for(int i=1;i<=r;i++) for (int j=1;j<=c;j++){ cin>>ch; if (ch=='.') a[i][j]=1; if(ch=='S') {x0=i;y0=j;a[i][j]=1;} if(ch=='T'){x1=i;y1=j;a[i][j]=1;} } if (x0==x1&&y0==y1) {cout<<0<<endl; return 0;} bfs(); cout<<minc<<endl; return 0; }