题目传送门

题意:一个人去救女朋友,两个人都在运动,还有鬼在"扩散",问最少几秒救到女朋友

分析:开两个队列来表示两个人走过的路,一个人走到的地方另一个人已经vis了,那么就是相遇了,鬼就用曼哈顿距离判断.

#include <bits/stdc++.h>
using namespace std; const int N = 8e2 + 5;
char maze[N][N];
int n, m;
bool vis[N][N][2];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
struct Point {
int x, y;
Point() {}
Point(int x, int y) : x (x), y (y) {}
};
queue<Point> que[2];
Point mm, gg, gho[2]; int get_dis(int x, int y, int ex, int ey) {
return abs (ex - x) + abs (ey - y);
} bool check2(int x, int y, int tim) {
for (int i=0; i<2; ++i) {
if (get_dis (x, y, gho[i].x, gho[i].y) <= 2 * tim) return false;
}
return true;
} bool check(int x, int y, int typ) {
if (x < 1 || x > n || y < 1 || y > m || maze[x][y] == 'X') return false;
else return true;
} void init(void) {
while (!que[0].empty ()) que[0].pop ();
while (!que[1].empty ()) que[1].pop ();
memset (vis, false, sizeof (vis));
} bool BFS(int typ, int tim) {
int sz = que[typ].size ();
while (sz--) {
Point u = que[typ].front (); que[typ].pop ();
if (!check (u.x, u.y, typ) || !check2 (u.x, u.y, tim)) continue;
for (int i=0; i<4; ++i) {
int tx = u.x + dx[i], ty = u.y + dy[i];
if (!check (tx, ty, typ) || !check2 (tx, ty, tim)) continue;
if (vis[tx][ty][typ^1]) return true;
if (vis[tx][ty][typ]) continue;
vis[tx][ty][typ] = true;
que[typ].push (Point (tx, ty));
}
}
return false;
} int run(void) {
init ();
vis[mm.x][mm.y][0] = true;
vis[gg.x][gg.y][1] = true;
que[0].push (Point (mm.x, mm.y));
que[1].push (Point (gg.x, gg.y));
int step = 0;
while (!que[0].empty () || !que[1].empty ()) {
++step;
for (int i=0; i<3; ++i) {
if (BFS (0, step)) return step;
}
if (BFS (1, step)) return step;
}
return -1;
} int main(void) {
int T; scanf ("%d", &T);
while (T--) {
scanf ("%d%d", &n, &m);
for (int i=1; i<=n; ++i) {
scanf ("%s", maze[i] + 1);
}
int t = 0;
for (int i=1; i<=n; ++i) {
for (int j=1; j<=m; ++j) {
if (maze[i][j] == 'M') {
mm.x = i; mm.y = j;
}
else if (maze[i][j] == 'G') {
gg.x = i; gg.y = j;
}
else if (maze[i][j] == 'Z') {
gho[t].x = i; gho[t++].y = j;
}
}
}
printf ("%d\n", run ());
} return 0;
}

  

BFS(双向) HDOJ 3085 Nightmare Ⅱ的更多相关文章

  1. HDU 3085 Nightmare Ⅱ(噩梦 Ⅱ)

    HDU 3085 Nightmare Ⅱ(噩梦 Ⅱ) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  2. HDU - 3085 Nightmare Ⅱ

    HDU - 3085 Nightmare Ⅱ 双向BFS,建立两个队列,让男孩女孩一起走 鬼的位置用曼哈顿距离判断一下,如果该位置与鬼的曼哈顿距离小于等于当前轮数的两倍,则已经被鬼覆盖 #includ ...

  3. UVA - 1601 The Morning after Halloween (BFS/双向BFS/A*)

    题目链接 挺有意思但是代码巨恶心的一道最短路搜索题. 因为图中的结点太多,应当首先考虑把隐式图转化成显式图,即对地图中可以相互连通的点之间连边,建立一个新图(由于每步不需要每个鬼都移动,所以每个点需要 ...

  4. UVa 1601 || POJ 3523 The Morning after Halloween (BFS || 双向BFS && 降维 && 状压)

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

  5. HDU 3085 Nightmare II 双向bfs 难度:2

    http://acm.hdu.edu.cn/showproblem.php?pid=3085 出的很好的双向bfs,卡时间,普通的bfs会超时 题意方面: 1. 可停留 2. ghost无视墙壁 3. ...

  6. HDU 3085 Nightmare Ⅱ (双向BFS)

    Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  7. HDU 3085 Nightmare Ⅱ(双向BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 题目大意:给你一张n*m地图上,上面有有 ‘. ’:路 ‘X':墙 ’Z':鬼,每秒移动2步,可 ...

  8. HDU 3085 Nightmare Ⅱ 双向BFS

    题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...

  9. 【HDOJ】3085 Nightmare Ⅱ

    双向BFS.注意,任何一个点出队后,首先需要考虑ghost. /* 3085 */ #include <iostream> #include <queue> #include ...

随机推荐

  1. 在cmd窗口中运行php命令

    1.首先安装php.我使用的是wamp,里面包含php5.5.12 2.将C:\wamp\bin\php\php5.5.12添加到环境变量Path中 3.在cmd中运行php -v可以查看php版本相 ...

  2. windows一个目录下最大文件数目

    对于FAT16文件系统, 可以保存的文件体积最大值是 4 GB - 1 byte (2^32 bytes - 1 byte): 卷的最大体积是4GB:每个卷上最多可以保存的文件数量是65,536个 ( ...

  3. 解决eclipse ctrl+鼠标左键不能用

    选择[Window]菜单 Preferences ——>General——>Editors——>Text Editors——>Hyperlinking 把勾都点上,然后确定KE ...

  4. C++异常层次结构图

  5. 4.2 set和multiset

    使用必须包含头文件set 1)multiset *:定义 如果不给第二个参数,默认less<key>,即用<来进行. 例如: A是一个类的名字,则可以定义一个容器对象如下: mult ...

  6. Python lambda函数使用

  7. MyEclipse 选中右侧编辑的文件时自动展开左侧目录树

  8. RMAN恢复目录

    是否使用RMAN恢复目录(Recovery Catalog 你可能从其他人或书上听过RMAN恢复目录(也有可能是其他名字,RMAN Recovery Catalog的翻译较多较杂,以下简称恢复目录), ...

  9. 【leetcode】Remove Duplicates from Sorted Array

    题目描述: Given a sorted array, remove the duplicates in place such that each element appear only once a ...

  10. myeclipse+tomcat 工程名改名的问题 ——————完美解决方案

    当建好的工程再重命名之后,发布和访问的时候都还是原来的名字,这个问题纠结了我很久,最好找到解决方法,这里分享一下,希望大家不要再受这种困惑.解决方法: 点击工程右键->properties-&g ...