Nightmare Ⅱ

Time Limit: 2000/1000 MS (Java/Others)    

Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 886    

Accepted Submission(s): 185

Problem Description

Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were trapped in a big maze separately. More terribly, there are two ghosts in the maze. They will kill the people. Now little erriyue wants to know if he could find
his girl friend before the ghosts find them.

You may suppose that little erriyue and his girl friend can move in 4 directions. In each second, little erriyue can move 3 steps and his girl friend can move 1 step. The ghosts are evil, every second they will divide into several parts to occupy the grids
within 2 steps to them until they occupy the whole maze. You can suppose that at every second the ghosts divide firstly then the little erriyue and his girl friend start to move, and if little erriyue or his girl friend arrive at a grid with a ghost, they
will die.

Note: the new ghosts also can devide as the original ghost.
 

Input
The input starts with an integer T, means the number of test cases.

Each test case starts with a line contains two integers n and m, means the size of the maze. (1<n, m<800)

The next n lines describe the maze. Each line contains m characters. The characters may be:

‘.’ denotes an empty place, all can walk on.

‘X’ denotes a wall, only people can’t walk on.

‘M’ denotes little erriyue

‘G’ denotes the girl friend.

‘Z’ denotes the ghosts.

It is guaranteed that will contain exactly one letter M, one letter G and two letters Z. 
 

Output
Output a single integer S in one line, denotes erriyue and his girlfriend will meet in the minimum time S if they can meet successfully, or output -1 denotes they failed to meet.
 

Sample Input

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

 

Sample Output

1
1
-1
 

Author
二日月
 

Source

n*m地图上有

‘. ’:路

‘X':墙

’Z':鬼,每秒蔓延2个单位长度,可以穿墙,共两个,每秒开始时鬼先动

‘M’:一号,每分钟可移动3个单位长度

‘G’:二号,每分钟课移动1个单位长度



解题心得:
1、这个题很明显的一个双向bfs,可能一开始会觉得是三个,因为还有一个幽灵的,但是幽灵每次走两格的距离,就可以直接按照x轴与y轴的距离的和step*2相比较看是否可以被鬼抓到。还有一点很重要的是每次都是鬼先走,所以在每次移动之前都要先判断一下。
2、这个题有个特点就是每一秒boy可以走三步,girl可以走一步,幽灵走两布,如果不写一个传递参数的函数代码的长度会很长,特别是在找bug和理框架的时候会很乱。所以平时在写一定功能的代码的时候要写成函数,并且多找找这些功能的共同点争取写成一个函数,思考怎么传递参数。
3、关于双向bfs,可以有多种操作,可以就在地图上操作,将一个bfs走过的地方全部化为当前,判断一个是否走到另一个的地盘。也可以在标记上面找,当一个的标记走到另一个已经标记的时候就算相遇,反正有比较多的方法可以进行判断,视情况和题意而定。


#include<bits/stdc++.h>
using namespace std;
const int maxn = 880;
int n,m;
int dir[4][2] = {1,0,-1,0,0,1,0,-1};
char maps[maxn][maxn];
struct node
{
int x,y;
} now,Next,b,g,z[2];
queue <node> q[2],qt;//q[0]为boy,q[1]为girl,qt为当前操作的队列
int step = 0;
void pre_maps()
{
//多组输入,清零
while(!q[0].empty())
q[0].pop();
while(!q[1].empty())
q[1].pop();
while(!qt.empty())
qt.pop(); int k = 0;
for(int i=0; i<n; i++)
scanf("%s",maps[i]);
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
if(maps[i][j] == 'Z')
{
z[k].x = i;
z[k].y = j;
k++;
}
if(maps[i][j] == 'M')
{
b.x = i;
b.y = j;
}
if(maps[i][j] == 'G')
{
g.x = i;
g.y = j;
}
}
} bool check(node a)
{
if(a.x <0 || a.y <0 || a.x >= n || a.y >= m)//超出地图直接返回
return true;
for(int i=0; i<2; i++)
{
if(maps[a.x][a.y] == 'X' || (abs(a.x-z[i].x)+abs(a.y-z[i].y)) <= 2*step)//是墙,或者被鬼抓到返回
return true;
}
return false;
}
bool bfs(int k,int num,char start,char End)
{
qt = q[k];//用来表示当前层的搜索,队列也可以直接赋值
for(int i=0; i<num; i++)
{
while(!qt.empty())
{
now = qt.front();
qt.pop();
q[k].pop();
if(check(now)) continue;
for(int j=0; j<4; j++)
{
Next.x = now.x + dir[j][0];
Next.y = now.y + dir[j][1];
if(check(Next)) continue;
if(maps[Next.x][Next.y] == start) continue;//已经走过了
if(maps[Next.x][Next.y] == End)//两个bfs相遇
return true;
maps[Next.x][Next.y] = start;//走过的地点直接标记
q[k].push(Next);
}
}
qt = q[k];//将下一层的队列赋值给当前层
}
return false;
} int solve()
{
bool flag1 = false,flag2 = false;
step = 0;
q[0].push(b);
q[1].push(g);
while(!q[0].empty() && !q[1].empty())
{
step++; flag1 = bfs(0,3,'M','G');//boy的bfs
flag2 = bfs(1,1,'G','M');//girl的bfs
if(flag1 || flag2)//当有一方相遇了
return step;
}
return -1;//没有找到
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
pre_maps();
printf("%d\n",solve());
}
}



BFS:HDU3085-Nightmare Ⅱ(双向BFS)的更多相关文章

  1. HDU3085 Nightmare Ⅱ —— 双向BFS + 曼哈顿距离

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Other ...

  2. HDU3085 Nightmare Ⅱ (双向BFS)

    联赛前该练什么?DP,树型,状压当然是爆搜啦 双向BFS就是两个普通BFS通过一拼接函数联系,多多判断啦 #include <iostream> #include <cstdio&g ...

  3. POJ 1915-Knight Moves (单向BFS &amp;&amp; 双向BFS 比)

    主题链接:Knight Moves 题意:8个方向的 马跳式走法 ,已知起点 和终点,求最短路 研究了一下双向BFS,不是非常难,和普通的BFS一样.双向BFS只是是从 起点和终点同一时候開始搜索,可 ...

  4. HDU 3085 Nightmare Ⅱ (双向BFS)

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

  5. HDU3085(双向BFS+曼哈顿距离)题解

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

  6. HDU 3085 Nightmare Ⅱ 双向BFS

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

  7. HDU3085(KB2-G 双向bfs)

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

  8. HDU——1195Open the Lock(双向BFS)

    Open the Lock Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) To ...

  9. Nightmare Ⅱ(双向BFS)

    Problem Description Last night, little erriyue had a horrible nightmare. He dreamed that he and his ...

随机推荐

  1. Caused by: java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V

    项目中各种缺包现象... Caused by: java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(I)V ...

  2. Cocos2d-x v3.1 安装图文教程(二)

       Cocos2d-x v3.1 安装图文教程(二) 如果我们需要在Android平台上运行就必须安装android的SDK,如果我们只想在window上运行就只需要安装Cocos2d-x就行了.当 ...

  3. [opencv3.2cmake error ] sys/videoio.h no such file or directories

    I don't have /usr/include/sys/videoio.h at all Before that , I have ipp download question. So I down ...

  4. zabbix中监控项报错

    报错信息: zabbix报错(Not all processes could be identified, non-owned process info will not be shown, you ...

  5. nmap --script http-enum,http-headers,http-methods,http-php-version -p 80 目标域

    从http服务器上收集到更多地信息 nmap --script http-enum,http-headers,http-methods,http-php-version  -p 80 目标域

  6. Linux让Apache支持中文URL图片/文件名

    需要用到iconv_hook和mod_encoding Apache(32位): 安装环境:CentOS 5.6 + Apache 2.2.15 (Apache2.4同样适用) 安装结果:安装后支持“ ...

  7. LeetCode Valid Palindrome 有效回文(字符串)

    class Solution { public: bool isPalindrome(string s) { if(s=="") return true; ) return tru ...

  8. SAP成都研究院非典型程序猿,菜园子小哥:当我用UI5诊断工具时我用些什么

    身边有些年轻同事曾经向我表达过这种困扰:尽管完成日常工作没有任何问题,但是还想更进一步,把代码写得更好些,做到精益求精.现在写的代码能实现功能,但是不知道可以怎样写得更好. 除了阅读优秀的开源库开源框 ...

  9. Liunx开发(Extjs4.1+desktop+SSH2超强视频教程实践)(2)

    然后装eclipse: 为啥默认是搜狗导航: java还没装呢: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downlo ...

  10. 修改CAS实现控制某个用户在定义的时间内登录次数

    思想: 在数据库增加字段  1.登录次数 2.登录失败时间(类型TimeStamp) 当一个用户进来认证的时候当登录失败的时候更新登录次数 和最后登录失败的时间. 主要是在登录成功或者失败的时候判断时 ...