美文网首页
xy+状态_三维bfs

xy+状态_三维bfs

作者: ffffffffffffly | 来源:发表于2019-01-31 11:45 被阅读0次

2019牛客网寒训#C---走迷宫

题目描述

精通程序设计的 Applese 双写了一个游戏。
在这个游戏中,它被困在了一个 n×m
的迷宫中,它想要逃出这个迷宫。

在迷宫中,有一些方格是水池,只有当 Applese 处于水属性的时候才可以通过;有一些方格是岩浆,只有当 Applese 是火属性的时候可以通过;有一些方格是墙壁,无论如何都无法通过;另一些格子是空地(包括起点和终点),可以自由通过。

在一些空地上有神秘道具可以让 Applese 转换自己的属性(从水属性变为火属性或从火属性变为水属性,需要一个单位的时间)。

已知 Applese 在一个单位的时间内可以朝四个方向行走一格,且开始处于水属性,位于空地的道具拾取后只能在该处立即使用(或者不使用),且可以多次使用。求它走出迷宫需要的最少时间。

输入描述:

第一行两个正整数 n, m 表示迷宫的大小。
接下来 n 行,每行长度为 m 的字符串。描述地图。
其中 'S' 表示起点,'T' 表示终点,'.' 表示空地,'w'表示岩浆,'~'表示水池,'@' 表示道具,'#'表示障碍。
保证地图中的起点和终点只有一个,道具都位于空地。

输出描述:

输出一个整数,表示 Applese 走出迷宫的最短时间。特别地,如果 Applese 走不出迷宫,输出 "-1"。

示例1

输入
5 5
.w@..
.S#..
~w#..
.w..~
@w.~T

输出
18

备注:

1≤n,m≤100

思路:求最短时间,典型的广搜,但这题多了一个水和火的状态,大佬说可以类似看成是3维空间,坐标x,y和状态;3维vis数组可以用于标记某一状态下走过的路径,如果状态不变,则走过的路径不要再重复走(妙呀!);注意要维护队列,使其保持时间的最小值(那个if的位置,把当前节点转换后的状态压入队列)。

代码:

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;

struct node{
    int x, y, t, state;  //可以把题意考虑成三维空间,坐标【x】,【y】和状态【水、火】
}nod;
int dir[][2] = {-1,0,1,0,0,1,0,-1};
char mp[105][105];
bool vis[105][105][2];  //state不变,则不要再走已经走过的路径
queue <node> que;
int n, m;
int bfs(int x, int y)
{
    nod.x = x, nod.y = y;
    nod.state = 0, nod.t = 0; //水的状态为0
    que.push(nod);
    while(!que.empty()){
        nod = que.front();
        que. pop();
        if(mp[nod.x][nod.y] == 'T')
            return nod.t;
        for(int i=0; i<4; ++i){
            int tx = nod.x + dir[i][0], ty = nod.y + dir[i][1], tst = nod.state;
            if(tx < n && ty < m && tx >= 0 && ty >= 0 && !vis[tx][ty][tst])  //border
                if(mp[tx][ty]=='S' || mp[tx][ty]=='T' || mp[tx][ty]=='@' || mp[tx][ty]=='.' || (mp[tx][ty]=='w' && tst==1) || (mp[tx][ty]=='~' && tst==0)){
                    que.push(node{tx, ty, nod.t+1, tst});  //可缩短代码长度
                    vis[tx][ty][tst] = 1;
                }
        }
        //下面的if不能放在for里面,要维护队列,保持时间是最小的、
        //也不能在for里面把@分两种情况讨论,变换水火的状态会变化时间,+2,+1的差异会使时间不能保持最小
        if(mp[nod.x][nod.y] == '@' && !vis[nod.x][nod.y][!nod.state]){ //转换当前点的状态
            que.push(node{nod.x, nod.y, nod.t+1, !nod.state});  //把转换后的状态压入队列
            vis[nod.x][nod.y][nod.state] = 1;
        }
    }
    return -1;
}

int main()
{
    int sx, sy;
    while(~scanf("%d%d", &n, &m)){
        memset(vis, 0, sizeof(vis));
        while(!que.empty()) que.pop();
        for(int i=0; i<n; ++i){
            for(int j=0; j<m; ++j){
                scanf(" %c", &mp[i][j]);
                if(mp[i][j] == 'S')
                    sx = i, sy = j;
            }
        }
        printf("%d\n", bfs(sx, sy));
    }
    return 0;
}

相关文章

  • xy+状态_三维bfs

    2019牛客网寒训#C---走迷宫 题目描述 精通程序设计的 Applese 双写了一个游戏。在这个游戏中,它被困...

  • 简单搜索总结

    A题棋盘问题,简单的递归问题,1A,速度上还是可以加快的。B题Dungeon Master,简单的三维BFS,1A...

  • poj1753(状态压缩 + bfs)

    题意:给你一个4 x 4的正方形,共有16个格子,每个格子要么是黑色,要么是白色。当把一个格子的颜色改变(黑->白...

  • 走迷宫(BFS例题)

    BFS例题---走迷宫 BFS对应数据结构queue BFS算法时间复杂度O(n^2) BFS算法不走走过的点 的...

  • poj2251(bfs)

    kuangbin带你飞搜索专题:poj2251这是一道三维bfs裸题..二维的最短路径相信大家都很熟悉,此题从二维...

  • 什么时候用BFS,什么时候用DFS

    参考什么时候用dfs,什么时候用bfs 参考什么时候用DFS,什么时候用BFS? BFS的缺点适用情况 BFS的一...

  • Binary Tree(2)

    BFS vs DFS for Binary Tree What are BFS and DFS for Binar...

  • BFS/DFS python模板与实现

    BFS BFS在搜索完第k层的节点之前,是不会搜索第k+1层的节点的。 BFS原理 BFS所用的是队列。把每个还没...

  • 2020-09-05

    BFS 队列的使用:queue<类型> q, q.push(k)(将状态k放入队列尾部), q.empty()(检...

  • Chapter12—搜索—广搜

    1. 题目列表 POJ3126(BFS) POJ3087(BFS) POJ3414(BFS+路径打印) 2. 广搜...

网友评论

      本文标题:xy+状态_三维bfs

      本文链接:https://www.haomeiwen.com/subject/fmsksqtx.html