原题链接,但是HDU现在校外提交需要审核
欢迎来 SCPC OJ提交
知识点 : BFS(广搜/宽搜)

原题:

描述:

可怜的公主在一次次被魔王掳走一次次被骑士们救回来之后,而今,不幸的她再一次面临生命的考验。魔王已经发出消息说将在T时刻吃掉公主,因为他听信谣言说吃公主的肉也能长生不老。年迈的国王正是心急如焚,告招天下勇士来拯救公主。不过公主早已习以为常,她深信智勇的骑士LJ肯定能将她救出。
现据密探所报,公主被关在一个两层的迷宫里,迷宫的入口是S(0,0,0),公主的位置用P表示,时空传输机用#表示,墙用*表示,平地用.表示。骑士们一进入时空传输机就会被转到另一层的相对位置,但如果被转到的位置是墙的话,那骑士们就会被撞死。骑士们在一层中只能前后左右移动,每移动一格花1时刻。层间的移动只能通过时空传输机,且不需要任何时间。

输入描述:
输入的第一行C表示共有C个测试数据,每个测试数据的前一行有三个整数N,M,T。 N,M迷宫的大小NM(1 <= N,M <=10)。T如上所意。接下去的前NM表示迷宫的第一层的布置情况,后N*M表示迷宫第二层的布置情况。
输出描述:
如果骑士们能够在T时刻能找到公主就输出“YES”,否则输出“NO”。

思路:

由题目可知此迷宫一共有两层,踩到#(传送门)会被瞬间传送到另外一层,可以知道如果另外一层该位置也是#就会陷入死循环,骑士就出不来了。显然这种走迷宫的问题应该考虑DFS和BFS。
此处我们使用BFS。通过对路径的记忆化来确定路线并为搜索完成后对路线用时的统计。
因为传送门是瞬时的,故路程计算不需要考虑吧,进入BFS判断前将坐标转换为另外一层的即可。
所以进入BFS的坐标条件是:

  • 该点坐标在地图范围内。
  • 该点坐标未被遍历过。
  • 该点坐标不是墙。
  • 该点坐标不是传送门(因为在进入判断前已经处理过是否为传送门的情况了,若此时依然为传送门,则说明是两个传送门嵌套,会死循环,故该点不可走)

具体实现:

  • 地图: 通过一个三维数组来模拟。其中一层和二层分别用01来区别,这样可以在遇到传送门时直接将层数坐标对1进行异或操作,使代码更加简洁。
  • 移动: 使用一个二维数组来模拟向各个方向走时候xy的变化量。不要使用move做变量名
    int mov[8][2] = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{1,-1},{-1,-1}};
  • 坐标在队列中的储存: 因为BFS是用队列来实现的,故我们存坐标通过定义一个结构体来实现(可能也可以通过tuple模板来实现,但菜菜不会qwq)
  • 对路径的记忆化: 通过再建一个三维数组来记录每个点的前一个点,这样就可以从终点一路回溯到起点
  • 路径长度的获取: 将从终点到起点的路径存入vector容器,然后获取vector容器中的元素个数即可。

蒟蒻的代码

#include<bits/stdc++.h>
#define close(); std::ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);
using namespace std;
//#define PI acos(-1)
//#define int long longconst int N = 1000005;//1e6+5
int n, m, tim;//定义为全局变量便于函数调用char mp[15][15][2];//地图创建
int mov[8][2] = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,1},{1,-1},{-1,-1}};//移动的参数
bool st[15][15][2];//存储点是否可以已被遍历
struct ZB{int x, y, z;
};//存储坐标
ZB dis[15][15][2];//记录上一步数组变量
ZB ed;//记录终点的遍历
queue<ZB> q;//bfs是依托于队列实现的
void bfs(){ZB t;st[0][0][0] = 1;t.x = 0;t.y = 0;t.z = 0;//导入队列第一个数据q.push(t);while(!q.empty()){  //已队列是否空作为结束条件t = q.front();//获取队头q.pop();//将搜索过的坐标移出队列for(int i = 0; i < 4; i++){ //因为是四个方向移动,故小于4(于上方的mov[]配合得到)int dx = t.x + mov[i][0];//得到下一步的坐标int dy = t.y + mov[i][1];int dz = t.z;if(mp[dx][dy][dz] == '#'){  //对传送门的特殊处理st[dx][dy][dz] = 1;dz = dz ^ 1;} if(dx < 0 || dx >= n || dy < 0 || dy >= m || mp[dx][dy][dz] == '*' || mp[dx][dy][dz] == '#' || st[dx][dy][dz])//判断是否可以进行搜索continue;st[dx][dy][dz] = 1; //标记已访问dis[dx][dy][dz] = t; //记录上一步ZB k;k.x = dx;k.y = dy;k.z = dz;q.push(k); //将当前坐标存入队列if(mp[dx][dy][dz] == 'P')ed = k; //记录终点坐标}}
}signed main(){close(); //关同步流(看宏定义)int timecs;ZB zoo;//用于初始化dis[]zoo.x = 0;zoo.y = 0;zoo.z = 0;cin>> timecs;while(timecs--){ed = zoo;cin>> n >> m >> tim;string sqwe;//为了方便输入定义的变量for(int i = 0; i < n; i++){//输入第一层,同时初始化第一层cin>> sqwe;for(int j = 0; j < m; j++){mp[i][j][0] = sqwe[j];st[i][j][0] = 0;//对状态初始化dis[i][j][0] = zoo;//对记忆的数据清除}}for(int i = 0; i < n; i++){//输入第二层,同时初始化第二层cin>> sqwe;for(int j = 0; j < m; j++){mp[i][j][1] = sqwe[j];st[i][j][1] = 0;dis[i][j][1] = zoo;}}bfs(); //宽搜if(mp[ed.x][ed.y][ed.z] != 'P') cout<<"NO"<<endl; //判断是否走到了终点else{ZB ll;ll = ed;dis[0][0][0].x = -1; //将起点特殊化,使其成为结束的信号vector<ZB> ak;while(ll.x != -1){ak.push_back(ll);ll = dis[ll.x][ll.y][ll.z];//将ll的数据变为ll的上一步的数据}if(ak.size() - 1 > tim) cout<<"NO"<<endl; //判断用时与题目限制时间的关系else cout<<"YES"<<endl;ak.clear();// 对vector容器清空}}return 0;
}

本篇完……
有很多不足之处,望诸位大佬海涵,也望诸位大佬不吝笔墨,指点迷津

最后,欢迎大家来SCPC OJ玩!!!

HDU 2102 题解(BFS 广度优先搜索 练习题)相关推荐

  1. LeetCode-笔记-199. 二叉树的右视图——BFS广度优先搜索

    LeetCode-笔记-199. 二叉树的右视图 199. 二叉树的右视图 给定一棵二叉树,想象自己站在它的右侧,按照从顶部到底部的顺序,返回从右侧所能看到的节点值. 示例: 输入: [1,2,3,n ...

  2. PTA:7-102 喊山 (30分)---解析(bfs广度优先搜索,vector)

    7-102 喊山 (30分) 喊山,是人双手围在嘴边成喇叭状,对着远方高山发出"喂-喂喂-喂喂喂--"的呼唤.呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的& ...

  3. 利用BFS广度优先搜索还原二阶魔方

    利用BFS广度优先搜索还原二阶魔方 采用BFS深度优先搜索算法进行了对于魔方求解问题的建模,并且利用C++代码进行了算法实现,能够实现输入魔方状态,自动输出解法的效果. BFS是图论中一种基本的搜索算 ...

  4. 步步为营(十六)搜索(二)BFS 广度优先搜索

    上一篇讲了DFS,那么与之相应的就是BFS.也就是 宽度优先遍历,又称广度优先搜索算法. 首先,让我们回顾一下什么是"深度": 更学术点的说法,能够看做"单位距离下,离起 ...

  5. [ACM_NYOJ_21]三个水杯(BFS广度优先搜索)

    三个水杯 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 给出三个水杯,大小不一,并且只有最大的水杯的水是装满的,其余两个为空杯子.三个水杯之间相互倒水,并且水杯没有标识,只 ...

  6. 哈理工OJ 1490 咒语(BFS广度优先搜索)

    咒语 Time Limit: 1000 MS Memory Limit: 65535 K Total Submit: 162(37 users) Total Accepted: 53(35 users ...

  7. 农夫过河游戏的几种处理方法(DFS深度优先搜索,BFS广度优先搜索)

    农夫过河游戏规则:在左岸有农夫.狼.羊.菜,农夫需要想办法将狼.羊.菜最终都带到右岸,条件就是农夫不在的时候,狼会吃羊,羊会吃菜,而且每次只能带一样,或者不带. 这里会用到堆栈.队列.列表这样的数据结 ...

  8. 【BFS 广度优先搜索】详解感染橘子最短时间问题

    一.题目描述 在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一: 值 0 代表空单元格: 值 1 代表新鲜橘子: 值 2 代表腐烂的橘子. 每分钟,腐烂的橘子 周围 4 个方向 ...

  9. 「BFS广度优先搜索」

    文章目录 0 回顾 1 BFS 2 刷题 2.1 二叉树的最小深度 2.1.1 题解 2.1.2 Code 2.1.3 结果 2.2 打开转盘锁 2.2.1 题解 2.2.2 Code 2.2.3 结 ...

最新文章

  1. 独家 | 一文读懂最大似然估计(附R代码)
  2. 移位运算[c][code]
  3. 如何对以破折号/连字符开头的字符串进行grep?
  4. 真正的云主机到底是什么样的?
  5. 软件开发中的几种数据交换协议
  6. C# 通过反射获取方法/类上的自定义特性
  7. 聚合,组合,继承的区别
  8. 【Linux下Inotify + Rsync文件实时同步】
  9. 对于最小割的进一步理解
  10. vb全局热键的写法(占很少的资源)
  11. Python 标准库 —— os 模块
  12. 远程桌面发生身份验证错误,要求的函数不受支持
  13. 根据Java源码生成流程图
  14. MySQL数据库知识点大全
  15. phpspider 简单使用
  16. Linux Server中搭建NAS存储服务(一)
  17. 分治法求数组最大最小数
  18. 小米2S进Recovery
  19. c#跳出循环break与continue
  20. 欢迎订阅我的专栏,好文章一网打尽

热门文章

  1. C#编程实现加密解密文件夹核心代码
  2. 手机使用教程_爷爷奶奶不会用手机,孙女手绘“使用教程”,网友:孝心让人感动...
  3. Android游戏音效控制
  4. 可枚举属性与不可枚举属性
  5. 文字游戏(java)
  6. UVA253 骰子涂色 C语言实现
  7. Cookie和Session、token粗解
  8. 工具系列——Eclipse中设置变量颜色及背景颜色自定义设置
  9. 增值你的C++技能,C++成为WEB后台“颜值 ”担当(一)
  10. 计算机组成原理教学网站,计算机组成原理教学网站