动态类迷宫中通常会出现其中一些特殊的物品,按一定周期进行变化。

我们假设迷宫中有一个楼梯,且是动态的,每隔一个单位时间,楼梯就会变换一次方向。楼梯的形状在开始时为 ‘-’ 或 ‘|’,表示其连接横向上的两个格子或纵向上的两个格子。 而当梯子转到另一方向(纵向)时,垂直于梯子方向(横向)是无法通行的。在此问题中允许蒜头君停留在某个除梯子的可行位子。
动态迷宫的具体输入为第一行 n 和 m 表示迷宫的行数和列数。接下来是一个 N 行 M 列的地图,‘*‘表示障碍物,’.‘表示走廊,’|’ 或者 ‘-’ 表示一个楼梯,并且标明了它在一开始时所处的位置:‘|‘表示的楼梯在最开始是竖直方向,’-’ 表示的楼梯在一开始是水平方向。地图中还有一个 ‘S’ 是蒜头君的位置,'T’是目标,0≤ N,M≤10,地图中不会出现两个相连的梯子。蒜头君每秒只能停留在 ‘.’ 或 ‘S’ 和 ‘T’ 所标记的格子内。

我们在分析这道题目时,我们发现整个迷宫的题字的周期是一致的,说明整个地图本质上只有两种状态,即奇数时间状态和偶数时间状态。
那么我们有什么策略吗?本质上,我们可以将一个位置分为两种状态考虑。分别记录一个位置上,奇数时间和偶数时间是否访问。那么对于之后的题目,如果整个迷宫的变化周题为T,那么我们也能够同样将一个位置拆分为T种状态。
对于这道题,我们拥有更巧妙的方案,实际上我们如果发现路径上需要通过梯子,且恰好再那个时刻梯子在另一个方向上,最直观的方案就是等待一个单位时间。其实这个等待操作也代表之前2种状态转化。

pause表示当前位置有没有停过。
我们需要枚举的是:

原本:u.x,u.y,u.tm,u.pause
当u.pause=false时
要枚举的是:
u.x+1,u.y,u.tm,u.pause=false
u.x-1,u.y,u.tm,u.pause=false
u.x,u.y+1,u.tm,u.pause=false
u.x,u.y-1,u.tm,u.pause=false
u.x,u.y,u.tm,u.pause=true
当然,在u.pause=true时
最后一种情况就不用了,只用枚举前4种即可

还有判断一下这个地方能不能走以及是否被访问过(前四种情况)

我们首先要处理遇到地图上的楼梯。对于纵向楼梯,我们需要分当前运动方向讨论。当我们横向运动时,只能在奇数时间通过;当我们以纵向运动时,我们只能在偶数时间通过。另外,由于梯子的特殊性,如果当前时间是可以通行,那么需要继续移动1格.

两种梯子就应该是:
在|的情况下,有两种情况,没有翻转时的坐标就应该是把x轴上的数-2,翻转后就应该是把y轴上的数+2。
在-的情况下,也有两种情况,没有翻转时的坐标就应该是把y轴上的数-2,翻转后就应该是把x轴上的数+2。
别忘了,最后还要处理最重要的停留操作,当然也很简单,就是当前如果还没停过,就让它停一次即可。
示例代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 25;
string s[N];
bool vis[N][N];
struct Node{int x, y, tm;bool pause;Node(){}Node(int _x, int _y, int _tm, bool _pause) {x = _x; y = _y; tm = _tm; pause = _pause;}
};
const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, -1, 1};
queue<Node> q;
int main()
{int n, m;cin >> n >> m;for(int i = 0; i < n; i++) {cin >> s[i];}pair<int, int> st;for(int i = 0; i < n; i++) {for(int j = 0; j < m; j++) {if(s[i][j] == 'S') {st = make_pair(i, j);}}}int ans = -1;q.push(Node(st.first, st.second, 0, false));vis[st.first][st.second] = 1;while(!q.empty() && ans == -1) {Node cur = q.front(); q.pop();for(int i = 0; i < 4; i++) {Node v = cur;v.x += dx[i];v.y += dy[i];v.tm++;v.pause = false;       if(v.x < 0 || v.x >= n || v.y < 0 || v.y >= m || vis[v.x][v.y]) continue;if(s[v.x][v.y]=='|'){if((i<2 && cur.tm%2==0)||(i>=2 && cur.tm%2==1)){v.x+=dx[i];v.y+=dy[i];if(vis[v.x][v.y] || s[v.x][v.y]=='*')continue;}elsecontinue;}    else if(s[v.x][v.y]=='-'){if((i<2 && cur.tm%2==1)||(i>=2 && cur.tm%2==0)){v.x+=dx[i];v.y+=dy[i];if(vis[v.x][v.y] || s[v.x][v.y]=='*')continue;}elsecontinue;}  if(s[v.x][v.y] == '.'){q.push(v);vis[v.x][v.y] = 1;} else if(s[v.x][v.y] == 'T') {ans = v.tm;break;}}if(!cur.pause){cur.pause=true;cur.tm++;q.push(cur);}}cout << ans << endl;return 0;
}

广度优先搜索——动态类迷宫问题相关推荐

  1. 广度优先搜索_计算机入门必备算法——广度优先遍历搜索

    1.  序言 又很久没有学习了,上次学到哈希表又称散列表的相关知识,这次我们学习一种新的数据结构来建立网络模型.这种数据结构被称作图.首先,我们先应该先了解一下什么是图,其次学习第一种图的算法,这种图 ...

  2. 广度优先搜索解决欧拉回路时间复杂度_迷宫搜索类的双向bfs问题(例题详解)

    前言 文章若有疏忽还请指正! 更多精彩还请关注公众号:bigsai 头条号:一直码农一直爽 在搜索问题中,以迷宫问题最具有代表性,无论是八皇后的回溯问题,还是dfs找出口,bfs找最短次数等等题目的问 ...

  3. 迷宫问题 深度优先搜索 广度优先搜索 宽度优先搜索【python】

    文章目录 一.实验内容 二.深度优先搜索和广度优先搜索总结 1.深度优先搜索算法 2.广度优先搜索算法 三.实验代码和用于测试的迷宫 1.实验代码 2.测试迷宫 2.1 maze1.txt 2.2 m ...

  4. 广度优先搜索 宽度优先搜索 迷宫问题 最短路径 最少操作 由近及远 队列

    广度优先搜索,也叫宽度优先搜索,从开始状态,到第一次能到达的状态,再从第一次能到达的状态到下一个能到达的状态,直到探索所有可到达的状态,其时间复杂度为O(状态数×转移的方式). 广度优先搜索使用了队列 ...

  5. 深度优先搜索和广度优先搜索及典例分析(走迷宫问题(BFS)和棋盘问题(DFS))

    搜索算法在实际编程应用中起着举足轻重的作用,学会掌握搜索算法并熟练应用搜索算法来解决实际问题不得不说是一件相当COOL的事,所以我将深度搜索和广度搜索认真地做了详细的总结,与诸君共勉,也方便以后查阅复 ...

  6. python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))...

    昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据.StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对象 ...

  7. 广度优先算法_算法浅谈——走迷宫问题与广度优先搜索

    本文始发于个人公众号:TechFlow,原创不易,求个关注 在之前周末LeetCode专栏当中,我们详细描述了深度优先搜索和回溯法,所以今天我们继续这个话题,来和大家聊聊搜索算法的另一个分支,广度优先 ...

  8. 广度优先搜索:迷宫问题

    用广度优先搜索解决迷宫问题是一个比较基础的方法.由于自己在算法方面基础不是很好,并没有达到能随手就写出BFS的水平,所以花了点时间写了一个BFS来解决比较基础的迷宫问题,权当练习,并供自己以后参考. ...

  9. 迷宫问题:深度优先搜索和广度优先搜索

    迷宫问题:深度优先搜索和广度优先搜索 1.深度优先搜索可以使用栈实现,栈顶元素为当前节点 2.当前节点搜索下一节点,判断节点是否走得通,如果走得通任意方向走一步,走不通一直弹出栈内元素,直到走得通 3 ...

最新文章

  1. python3.5下载-python3.5.2官方下载
  2. 矩阵元素求积及其矩阵元素的差分
  3. 在operator =中要处理“自我赋值”
  4. 表单内如何直接贴图而不用上传图片_表单如何添加图片?
  5. ASP.NET MVC 入门10、Action Filter 与 内置的Filter实现(实例-防盗链)
  6. linux 带ifdef运行程序_如何让linux的一段程序代码进入内核态运行
  7. Java多线程学习二十三:什么是阻塞队列
  8. SELinux系列(八)——SELinux默认安全上下文的查询和修改(semanage命令)
  9. android 进度gif,Android NumberProgressBar:动态移动显示百分比进度的进度条
  10. 如何自学计算机access,我是怎样自学access的
  11. android系统9有OTG功能吗,你的Android手机有OTG功能吗?没有我教你!
  12. 2021年CCPC网络预选赛重赛补题
  13. 微信小程序开发笔记1——使用npm脚本实现自动化切换环境配置
  14. 2023五一旅游必备物品清单!快记到手机待办APP里
  15. GiB 是什么?像 GB 是一样的吗?
  16. IObit Uninstaller pro:完全卸载程序,自动清除残余及注册表
  17. linux环境安装mysql8.0以及使用Navicat连接Linux中的mysql
  18. P14-前端基础-CSS属性选择器
  19. android 短信接口收拦截,给手机装“来点黑名单” 拒绝垃圾短信和电话
  20. C/C++ #include详解

热门文章

  1. redis为什么选择了跳跃表而不是红黑树
  2. 使用 Wall 搭建个人照片墙和视频墙
  3. xml与map的相互转换
  4. 旋转卡壳算法求最小外接矩形代码
  5. oracle数据库课程描述,《ORACLE数据库简介》课件.ppt
  6. 【100%通过率】华为OD机试真题 Python 实现【预订酒店】【2022.11 Q4 新题】
  7. mysql 重启监听器_Oracle Lsnrctl监听器的启动和关闭
  8. 淘宝直通车托管公司怎么样
  9. PCA主成分分析(降维)
  10. 阿里云ECS静态建站学习