zoukankan      html  css  js  c++  java
  • 6264:走出迷宫

    总时间限制: 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
  • 相关阅读:
    地址栏传值 JS取值方法
    定位导航 制作
    验证码
    图片水印
    AJAX 三级联动
    javascript 和Jquery 互转
    Jquery 事件 DOM操作
    Jquery 基础
    软件工程中的形式化方法读后感
    软件工程理论、方法与实践 需求工程读后感
  • 原文地址:https://www.cnblogs.com/ssfzmfy/p/5511288.html
Copyright © 2011-2022 走看看