原题链接: https://www.acwing.com/problem/content/179/

题目描述

给定一张N*M的地图,地图中有1个男孩,1个女孩和2个鬼。
字符“.”表示道路,字符“X”表示墙,字符“M”表示男孩的位置,字符“G”表示女孩的位置,字符“Z”表示鬼的位置。
男孩每秒可以移动3个单位距离,女孩每秒可以移动1个单位距离,男孩和女孩只能朝上下左右四个方向移动。
每个鬼占据的区域每秒可以向四周扩张2个单位距离,并且无视墙的阻挡,也就是在第k秒后所有与鬼的曼哈顿距离不超过2k的位置都会被鬼占领。
注意: 每一秒鬼会先扩展,扩展完毕后男孩和女孩才可以移动
求在不进入鬼的占领区的前提下,男孩和女孩能否会合,若能会合,求出最短会合时间。
输入格式
第一行包含整数T,表示共有T组测试用例。
每组测试用例第一行包含两个整数N和M,表示地图的尺寸。
接下来N行每行M个字符,用来描绘整张地图的状况。(注意:地图中一定有且仅有1个男孩,1个女孩和2个鬼)
输出格式
每个测试用例输出一个整数S,表示最短会合时间。
如果无法会合则输出-1。
每个结果占一行。
数据范围
1<n,m<800
输入样例:
3
5 6
XXXXXX
XZ…ZX
XXXXXX
M.G…

5 6
XXXXXX
XZZ…X
XXXXXX
M…
…G…
10 10

…X…
…M.X…X.
X…
.X…X.X.X.
…X
…XX…X.
X…G…X
…ZX.X…
…Z…X…X
输出样例:
1
1
-1

题解

这是一种BFS新的扩展方式,先把男孩每一步能扩展的区域标记为1,同时女孩每一步能扩展的区域标记为2,男孩与女孩能相遇的条件就是走过相同的区域。因为要维护每一步所有的区域。因此采用下面的方式

#include <iostream>
#include <queue>
#include <algorithm>
#include <cstring>using namespace std;
typedef pair<int, int> PII;
const int N = 810;
char g[N][N];
int n, m;
int st[N][N];
PII ghost[2];bool check(int x, int y, int step)
{if (x < 0 || x >= n || y < 0 || y >= m || g[x][y] == 'X') return false;for (int i = 0; i < 2; i ++ )if (abs(x - ghost[i].first) + abs(y - ghost[i].second) <= step * 2)return false;return true;
}int bfs()
{memset(st, 0, sizeof st);int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};PII boy, girl;int cnt = 0;for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){if(g[i][j] == 'M') boy = {i, j};else if(g[i][j] == 'G') girl = {i, j};else if(g[i][j] == 'Z') ghost[cnt++] = {i, j};}}queue<PII> qb, qg;qb.push(boy);qg.push(girl);int step = 0;while(qb.size() || qg.size()){step++;for(int i = 0; i < 3; i++){for(int j = 0, len = qb.size(); j < len; j++){auto t = qb.front();qb.pop();int x = t.first, y = t.second;if(!check(x, y, step)) continue; //这里要判断一下,因为第一次入队可能就不符合要求for(int k = 0;  k < 4; k++){int a = x + dx[k], b = y + dy[k];if(check(a, b, step)){if(st[a][b] == 2) return step;if(!st[a][b]){st[a][b] = 1;qb.push({a, b});}}}}}for(int i = 0; i < 1; i++){for(int j = 0, len = qg.size(); j < len; j++){auto t = qg.front();qg.pop();int x = t.first, y = t.second;if(!check(x, y, step)) continue;for(int k = 0;  k < 4; k++){int a = x + dx[k], b = y + dy[k];if(check(a, b, step)){if(st[a][b] == 1) return step;if(!st[a][b]){st[a][b] = 2;qg.push({a, b});}}}}}}return -1;
}int main()
{int T;cin >> T;while(T--){cin >> n >> m;for(int i = 0; i < n; i++) scanf("%s", g[i]);printf("%d\n", bfs());}return 0;
}

AcWing 177. 噩梦(双向BFS)相关推荐

  1. 算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map

    题目分析 来源:acwing 分析: 双向广搜主要用在最小步数模型(也称状态图模型)里面,这里整个状态空间一般是指数级别的,用双向广搜可以极大地提高运行效率. 双向广搜,顾名思义,就是从起点和终点都进 ...

  2. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  3. 吴昊品游戏核心算法 Round 9 —— 黑白棋AI系列之西洋跳棋(第二弹)(双向BFS+STL)(POJ 1198)...

    接上回,如图所示,这是黑白棋的一个变种,Solitaire也是一种在智能手机上普遍存在的一种游戏.和翻转棋(Flip Game)一样,西洋跳棋(Solitaire)也没有正统的黑白棋(奥赛罗,又称Ot ...

  4. 浅谈迷宫搜索类的双向bfs问题(例题解析)

    文章目录 前言 bfs类问题 双向bfs 例题实战 前言 文章若有疏忽还请指正,更多精彩还请关注公众号:bigsai 在搜索问题中,以迷宫问题最具有代表性,无论是八皇后的回溯问题,还是dfs找出口,b ...

  5. [题解](双向bfs)hdu_3085_Nightmare Ⅱ

    发现直接搜索比较麻烦,但是要同时两个人一起走容易想到双向bfs,比较普通, 在判断是否碰到ghost时只要比较两点的曼哈顿距离大小和step*2(即ghost扩散的距离)即可,仔细思考也是可以想到的 ...

  6. HDU - 3085 Nightmare Ⅱ(双向bfs)

    题目链接:点击查看 题目大意:给出一个迷宫,一个男孩和一个女孩还有两只鬼,男孩每秒钟走3格,女孩每秒钟走1格,鬼每秒钟向四周分裂2格,问男孩和女孩能否在鬼占领迷宫之前汇合,能的话输出汇合时间,否则输出 ...

  7. UVA1601The Morning after Halloween 单向加双向bfs

    题意:w*h(w,h16)网格上有n(n3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右四个方向之一移动),但每步结束之后任何两个鬼不能占用同一 ...

  8. [蓝桥杯][历届试题]九宫重排-双向bfs和map标记

    题目描述 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的局面记为:12 ...

  9. 走迷宫-双向bfs解法

    双向bfs适用于知道起点和终点的状态下使用,从起点和终点两个方向开始进行搜索,可以非常大的提高单个bfs的搜索效率 同样,实现也是通过队列的方式,可以设置两个队列,一个队列保存从起点开始搜索的状态,另 ...

  10. 数据结构实验之图论四:迷宫探索_迷宫搜索类的双向bfs问题(例题详解)

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

最新文章

  1. 14条改善jquery代码的建议
  2. rtsp中的rtp发送和head理解
  3. 10.11杭州Clouder lab 十分钟搭建共享应用 2:如何通过日志服务实现用户的日志收集与分析...
  4. Windows 7 提示AtBroke.exe初始化失败
  5. 【机器视觉】 halcon中图像获取
  6. 【高清】网络安全思维导图
  7. Linux db2 4499,db2 連接 ERRORCODE=-4499, SQLSTATE=08001,解決辦法
  8. Flinksql读取Kafka写入Iceberg 实践亲测
  9. 混合云是趋势?阿里云与私有云厂商 ZStack合作
  10. 2018双十一苏宁20+篇技术干货全整理
  11. SnapGene如何设计sgRNA,构建载体,对靶基因进行敲除
  12. 【比赛题解】第十一届蓝桥杯青少组省赛(中级组)详细题解
  13. 2021新年喜庆音乐中国风背景音乐素材共39首第二辑合集下载
  14. 人社部通知!2020年社保基数大调整、公积金必须同时缴纳、医保账户取消…
  15. C++如何获取虚函数表(vtbl)的内容及虚成员函数指针存放原理
  16. 2021年西式面点师(初级)及西式面点师(初级)模拟试题
  17. 文字内容超出两行时显示省略号
  18. 微信小程序点击查看大图
  19. Pytorch中tensor.view().permute().contiguous()函数理解
  20. 各种安装包的下载地址

热门文章

  1. php右侧弹窗QQ客服,网页右侧悬浮滚动在线qq客服代码示例_javascript技巧
  2. 三级联动(原生js)
  3. 木耳炒什么好吃 木耳的做法
  4. 小小光纤承载尖端技术 “中国制造”引领行业标准
  5. 互联网行业中最常用的数据库——MySQL数据库介绍
  6. 数学分析高等代数考研试题荟萃[更新至2017年12月28日]
  7. 离线地图三维立体建筑物实现
  8. 浅述狭义相对论的钟慢效应和尺缩效应
  9. mysql查看表编码_MySQL中使用SQL语句查看某个表的编码方法
  10. HTML小游戏4 —— 简易版英雄联盟(附完整源码)