总时间限制: 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;
}
View Code

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;
}
View Code

 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;
}
View Code

 

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;
}
View Code