迷宫二T1596 bfs与dfs

3 篇文章 0 订阅

一道经典迷宫题目:使用bfs与dfs都可以解,dfs时间复杂度高一点
非常非常好的题

Description>

第一行输入两个整数n和 m,表示这是一个 n×m 的迷宫。接下来的输入一个 n 行 m 列的迷宫。其中 ‘S’ 表示蒜头君的位置,’*‘表示墙,蒜头君无法通过,’.‘表示路,蒜头君可以通过’.'移动,'T’表示迷宫的出口(蒜头君每次只能移动到四个与他相邻的位置——上,下,左,右)。
输出蒜头君逃出迷宫的最少步数,如果蒜头君无法逃出迷宫输出 −1。
Inpot>

3 4
S**.
…*.
***T
Outpot>

-1
Inpot>

3 4
S**.
…*.
***T
Outpot>

5

首先是DFS的方法

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
int p,q; //迷宫出口
int m,n; //迷宫大小
char mmap[110][110];//迷宫
bool vis[110][110]; //标记
int mmin;
int a[4]={1,-1,0,0};
int b[4]={0,0,-1,1};

void dfs(int x,int y,int step)
{
    if(x==p && y==q){
       if(mmin>step){
        mmin = step;
       }
       return ;
    }
   for(int i=0;i<4;i++){
     int tx,ty;
     tx = x + a[i];
     ty = y + b[i];
     if(tx>=0&&ty>=0&&tx<n&&ty<m && vis[tx][ty]==0){
            if(mmap[tx][ty]=='.' || mmap[tx][ty]=='T'){
        vis[tx][ty] = 1;
        dfs(tx,ty,step+1);
        vis[tx][ty] = 0;
        }
     }
   }


}
int main()
{
    //memset(vis,0,sizeof(vis));
    //memset(mmap,'\0',sizeof(mmap));
    mmin=99999999;
    int i,j;
    int sx,sy; //迷宫入口
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++){
    for(j=0;j<m;j++){
        cin>>mmap[i][j]; //只能用%s和cin>>
        if(mmap[i][j] == 'T'){p = i; q = j;}//出口
        if(mmap[i][j] == 'S'){sx= i; sy= j;}//入口
        }
    }
    vis[sx][sy] = 1;//标记入口走过
    dfs(sx,sy,0); //步数0
    if(mmin==99999999) printf("-1\n");
    else  printf("%d\n",mmin);

    return 0;
}

BFS的方法

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;
int m,n; //迷宫大小
char mmap[110][110];//迷宫
bool vis[110][110]; //标记
int a[4]={1,-1,0,0};//四个方向
int b[4]={0,0,-1,1};//四个方向

struct node{
    int x,y,step;
};

bool check(int x,int y){
    if(x>=0&&x<n&&y>=0&&y<m&&mmap[x][y]!='*'&&vis[x][y]==0)
        return 1;
        return 0;
}
int bfs(int x,int y)
{
    queue<node>q;
    node p;
    p.x = x;
    p.y = y;
    p.step = 0;
    q.push(p);
    while(!q.empty()){
        p = q.front();
        q.pop();
        if(mmap[p.x][p.y]=='T')//到达出口跳出
            return p.step;
        for(int i = 0;i<4;i++){
            int xx = p.x + a[i];
            int yy = p.y + b[i];
            if( check(xx,yy) ){
                vis[xx][yy] = 1;
                node e;
                e.x = xx;
                e.y = yy;
                e.step = p.step+1;
                q.push(e);
            }
        }
    }
   return -1;
}
int main()
{
    int i,j;
    int sx,sy; //迷宫入口
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++){
    for(j=0;j<m;j++){
        cin>>mmap[i][j]; //只能用%s和cin>>
        if(mmap[i][j] == 'S'){sx= i; sy= j;}//入口
        }
    }
    vis[sx][sy] = 1;//标记入口走过
    printf("%d\n",bfs(sx,sy));

    return 0;
}

迷宫的升级版本还有路径输出以及利用优先+BFS解决加权问题
下面把上面改成了求路径问题,题目一样,只输出了路径。
利用BFS和队列

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<queue>
#include<algorithm>
#include<math.h>
using namespace std;
int m,n; //迷宫大小
char mmap[100][100];//迷宫
bool vis[100][100]; //标记
int a[4]={1,-1,0,0};//四个方向
int b[4]={0,0,-1,1};//四个方向
int tx,ty; //迷宫出口
int sx,sy; //迷宫入口
struct node{
    int x,y;
};
node pre[100][100];
bool check(int x,int y){
    if(x>=0&&x<n&&y>=0&&y<m&&mmap[x][y]!='*'&&vis[x][y]==0)
        return 1;
        return 0;
}
void bfs(int x,int y)
{
    queue<node>q;
    node p;
    p.x = x;
    p.y = y;
    q.push(p);
    while(!q.empty()){
        p = q.front();
        q.pop();
        if(mmap[p.x][p.y]=='T')//到达出口跳出
            return ;
        for(int i = 0;i<4;i++){
            node e;
            e.x = p.x + a[i];
            e.y = p.y + b[i];
            if( check(e.x,e.y) ){
                vis[e.x][e.y] = 1;
                q.push(e);
                pre[e.x][e.y] = p;
            }
        }
    }
}

void prin(node k){ //逆向输出
    if(sx==k.x&&sy==k.y) {
        printf("(0,0)\n");
        return ;
    }
    prin(pre[k.x][k.y]);
    printf("(%d,%d)\n",k.x,k.y);
}

int main()
{
    int i,j;
    scanf("%d%d",&n,&m);
    for(i=0;i<n;i++){
    for(j=0;j<m;j++){
        cin>>mmap[i][j]; //只能用%s和cin>>
        if(mmap[i][j] == 'T'){tx= i; ty= j;}//出口
        if(mmap[i][j] == 'S'){sx= i; sy= j;}//入口
        }
    }
    vis[sx][sy] = 1;//标记入口走过
    bfs(sx,sy);
    node k;
    k.x = tx,k.y = ty;
    prin(k);
    
    return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值