BFS--cf793b Igor and his way to work

本文介绍了一个迷宫寻路问题的解决方案,利用广度优先搜索(BFS)算法并结合方向和转弯次数的限制来寻找从起点到终点的路径。通过合理的设计数据结构和状态记录避免重复计算,确保了算法效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从起点走到终点,最多只能转2次弯,求是否能到达终点。

如果用dfs,会因为重复状态过多超时。

所以需要bfs,并且记录是否访问过。

由于有方向和转弯次数的限制,所以需要一起在vis中记录。

#include <iostream>

#include <cstdio>

#include <queue>

using namespace std;

const int maxn = 1000 + 5;

char mp[maxn][maxn];

const int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};

struct point {

    int x,y;

}s,t;

struct node{

    int x,y;

    int d,turn;//剩余的转弯次数

};

bool succ = false;

int vis[maxn][maxn][4][3];//x y dir turn

int n,m;


void bfs()

{

    queue<node> q;

    int tx,ty;

    for (int i = 0; i < 4; i ++) {

        tx = s.x + dir[i][0];

        ty = s.y + dir[i][1];

        if(tx >= 0 && ty >= 0 && tx < n && ty < m && mp[tx][ty] != '*'){

        q.push({tx,ty,i,2});

            vis[tx][ty][i][2] = 1;}

    }

    while (!q.empty()) {

        node tmp = q.front();q.pop();

        if(tmp.x == t.x && tmp.y == t.y) {succ = true;break;}

        for (int i = 0; i < 4; i ++) {

            int tx = tmp.x + dir[i][0];

            int ty = tmp.y + dir[i][1];

            if(tx >= 0 && ty >= 0 && tx < n && ty < m && mp[tx][ty] != '*'){

            if(i == tmp.d)

            {

                if(!vis[tx][ty][i][tmp.turn]){

                vis[tx][ty][i][tmp.turn] = 1;

                q.push({tx,ty,i,tmp.turn});

                }

            }

            else{

                if(tmp.turn > 0)

                {

                    if(!vis[tx][ty][i][tmp.turn - 1]){

                    vis[tx][ty][i][tmp.turn - 1] = 1;

                    q.push({tx,ty,i,tmp.turn - 1});

                    }

                }

            }

            }

        }

    }

}

int main()

{

    scanf("%d%d",&n,&m);

    getchar();

    for (int i = 0; i < n; i ++) {

        for (int j = 0; j < m; j ++) {

            scanf("%c",&mp[i][j]);

            if(mp[i][j] == 'S') {s.x = i,s.y = j;}

            else if (mp[i][j] == 'T') {t.x = i,t.y = j;}

        }

        getchar();

    }

    bfs();

    if(succ) printf("YES\n");

    else printf("NO\n");

    return 0;

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值