UPC(混合4补)问题 A: 走出迷宫

标签:BFS,DFS
时间限制: 1 Sec 内存限制: 128 MB

题目描述
当你站在一个迷宫里的时候,往往会被错综复杂的道路弄得失去方向感,如果你能得到迷宫地图,事情就会变得非常简单。
假设你已经得到了一个n×m的迷宫的图纸,请你找出从起点到出口的最短路。
输入
第一行是两个整数n和m,表示迷宫的行数和列数。
接下来n行,每行一个长为m的字符串,表示整个迷宫的布局。字符.表示空地,#表示墙,S表示起点,T表示出口。
输出
输出从起点到出口最少需要走的步数。
样例输入

3 5
T..##
#.#.S
#...#

样例输出

7

提示
对于100%的数据,保证1≤n,m≤100,保证从起点出发一定能到达出口。
解题思路一、DFS,把所有的方案走完,找到最小值

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <vector>
#include <queue>
#include <ctime>
#define ll long long
#define inf 0x3f3f3f3f
//#define local
using namespace std;
const int N = 105;
int n,m,bx,by,ex,ey,ans=inf;
char a[N][N];
int dir[4][2]= {1,0,-1,0,0,1,0,-1};
void dfs(int x,int y,int num)
{
    if(x==ex&&y==ey)
    {
        ans=min(num,ans);
        return ;
    }
    for(int i=0; i<4; i++)
    {
        x+=dir[i][0];
        y+=dir[i][1];
        if((a[x][y]=='.'||a[x][y]=='T')&&x>=1&&y>=1&&x<=n&&y<=m)
        {
            a[x][y]='#';
            dfs(x,y,num+1);
            a[x][y]='.';
        }
        x-=dir[i][0];
        y-=dir[i][1];
    }
 
}
int main()
{
#ifdef local
    freopen("input.txt","r",stdin);
#endif // local
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='S')
                bx=i,by=j;
            if(a[i][j]=='T')
                ex=i,ey=j;
        }
    }
    dfs(bx,by,0);
    printf("%d",ans);
    return 0;
}

DFS,又可理解为回溯算法,就是要在递归之前作出选择,之后撤销选择,直到找出min/max的值,就像一条路一条路的进行尝试,遍历完所有的选择之后,才能得出结果,往往时间复杂度很高,所以这道题,在意料之外又在情理之中的TLE了。
解题思路二、BFS

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <math.h>
#include <vector>
#include <queue>
#include <ctime>
#define ll long long
#define inf 0x3f3f3f3f
//#define local
using namespace std;
const int N = 105;
int n,m,bx,by,ex,ey,ans=0;
char a[N][N];
int vis[N][N];
int dir[4][2]= {1,0,-1,0,0,1,0,-1};
struct node
{
    int x,y,s;
};
void bfs(int u,int v)
{
    node temp,nex;
    temp.x=u;
    temp.y=v;
    temp.s=0;
    queue<node> q;
    q.push(temp);
    while(!q.empty())
    {
        temp=q.front();
        q.pop();
        for(int i=0; i<4; i++)
        {
            nex.x=temp.x+dir[i][0];
            nex.y=temp.y+dir[i][1];
            nex.s=temp.s+1;
            if(nex.x<0||nex.x>n||nex.y<0||nex.y>m||a[nex.x][nex.y]=='#'||vis[nex.x][nex.y]==1)
                continue;
            vis[nex.x][nex.y]=1;
            if(a[nex.x][nex.y]=='T')
            {
                ans=nex.s;
                return;
            }
            q.push(nex);
        }

    }
}
int main()
{
#ifdef local
    freopen("input.txt","r",stdin);
#endif // local
    scanf("%d%d",&n,&m);
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=m; j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='S')
                bx=i,by=j;
            if(a[i][j]=='T')
                ex=i,ey=j;
        }
    }
    memset(vis,0,sizeof(vis));
    bfs(bx,by);
    printf("%d",ans);
    return 0;
}

BFS,通常会借助于队列这种数据结构,这种方法找到的路径一定是最短路径。BFS借助队列做到一次一步,“齐头并进”,是可以在不完全遍历的情况下就得出最短路径的。但是相比于DFS,空间复杂度较高。

参考:
https://www.cnblogs.com/lipu123/p/12805950.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值