题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085

题目大意:给你一张n*m地图上,上面有有

  ‘. ’:路

  ‘X':墙

  ’Z':鬼,每秒移动2步,可以穿墙,开始有两个,每开始时鬼先动。

  ‘M’:男生,每秒可走3步。

  ‘G’:女生,每秒可走1步。

解题思路:第一次写双向BFS,写了我好久,开始还是想着先bfs计算step[x][y][t]把每个位置被鬼占据的时间处理一下然后再用双向BFS计算两人相遇时间。后来发现因为鬼可以穿墙,可以直接用曼哈顿距离判断是否会被鬼抓到。还有,开始我都不知道每秒走三步怎么搞。。。后来看了网上的博客,知道可以通用size限制一下出队数,三次bfs实现每秒走三步。太乱了,稍微总结一下:

     ①两人给vis[x][y]分别标记1,2当某次bfs遇到不同标记说明两人相遇。

     ②用曼哈顿距离判断时间t走到某个位置是否会被鬼抓到。

     ③因为鬼先行动,每次t+1时,在人行动前要判断在当前位置会不会被鬼抓到。

     ④用size=q[mark].size()控制每次出队数,实现一秒走三步。

     ⑤最坑爹的一点,用scanf("%c",&map[i][j])无限超时,感觉里面绝对有不正常的数据,后来用scanf("%s",map[i]+1)每次输入一行才过掉。

代码:

 #include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=; int n,m,t;
int d[][]={{-,},{,},{,-},{,}};
char map[N][N];
int vis[N][N]; struct node{
int x,y;
}M,G,pre,now,a[];
queue<node>q[]; bool judge(int x,int y){
if(x<||y<||x>n||y>m||map[x][y]=='X')
return false;
//利用曼哈顿距离判断是否会被鬼抓到
for(int i=;i<=;i++){
if(abs(x-a[i].x)+abs(y-a[i].y)<=*t)
return false;
}
return true;
} bool bfs(int mark){
//小技巧,利用size就可以控制出队的都是上一步的,而不会将这一步的也出队,就能实现走3步了。
int size=q[mark].size();
while(size--){
pre=q[mark].front();
q[mark].pop();
//鬼在人之前行动,时间每增加1,先判断鬼能不能把人吃掉
if(!judge(pre.x,pre.y))
continue;
for(int i=;i<;i++){
int xx=pre.x+d[i][];
int yy=pre.y+d[i][];
if(!judge(xx,yy))
continue;
//遇到不同标记说明两人相遇
if(vis[xx][yy]){
if(vis[xx][yy]!=mark)
return true;
else
continue;
}
vis[xx][yy]=mark;
now.x=xx;
now.y=yy;
q[mark].push(now);
}
}
return false;
} int solve(){
//清空队列
while(!q[].empty()) q[].pop();
while(!q[].empty()) q[].pop();
q[].push(M);
q[].push(G);
vis[M.x][M.y]=,vis[G.x][G.y]=;
t=;
//双向bfs
while(!q[].empty()||!q[].empty()){
t++;
for(int i=;i<=;i++){
if(bfs())
return t;
}
if(bfs())
return t;
}
return -;
} int main(){
int T;
scanf("%d",&T);
while(T--){
memset(vis,,sizeof(vis));
scanf("%d%d",&n,&m);
//注意用scanf("%c",map[i][j])会超时
for(int i=,cnt=;i<=n;i++){
scanf("%s",map[i]+);
for(int j=;j<=m;j++){
if(map[i][j]=='M')
M.x=i,M.y=j;
if(map[i][j]=='G')
G.x=i,G.y=j;
if(map[i][j]=='Z')
a[++cnt].x=i,a[cnt].y=j;
}
}
printf("%d\n",solve());
}
return ;
}

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

  1. HDU 3085 Nightmare Ⅱ (双向BFS)

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

  2. HDU 3085 Nightmare Ⅱ 双向BFS

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

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

    Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were tra ...

  4. HDU - 3085 Nightmare Ⅱ

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

  5. HDU 3085 Nightmare Ⅱ(噩梦 Ⅱ)

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

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

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

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

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

  8. 2017多校第10场 HDU 6171 Admiral 双向BFS或者A*搜索

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6171 题意: 给你一个高度为6的塔形数组,你每次只能将0与他上下相邻的某个数交换,问最少交换多少次可以 ...

  9. HDU 1242 -Rescue (双向BFS)&amp;&amp;( BFS+优先队列)

    题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出 ...

随机推荐

  1. activiti学习-用户与用户组

    activiti学习笔记3-用户与用户组 2015年05月07日 14:43:06 cq1982 阅读数:4142更多 个人分类: activiti工作流引擎   (本博客都是纯文本手工代码,错误难免 ...

  2. 【OpenCV】SIFT原理与源码分析:关键点搜索与定位

    <SIFT原理与源码分析>系列文章索引:http://www.cnblogs.com/tianyalu/p/5467813.html 由前一步<DoG尺度空间构造>,我们得到了 ...

  3. 洛谷P1106 删数问题

    题目描述 键盘输入一个高精度的正整数N,去掉其中任意k个数字后剩下的数字按原左右次序将组成一个新的正整数.编程对给定的N和k,寻找一种方案使得剩下的数字组成的新数最小. 输出应包括所去掉的数字的位置和 ...

  4. angular2 获取到的数据无法实时更新的问题

    在修改完组件数据之后调用下面两句: this.changeDetectorRef.markForCheck(); this.changeDetectorRef.detectChanges(); 注入到 ...

  5. windows 安装 apache 服务以及添加 php 解析

    apache 官方并没有提供 windows 的安装包,但是它们官网给出了第三方的链接,我们可以在那些第三方网站上找到适用于 windows 的二进制包. 我们点进去下载一个 64 位的, 下载完之后 ...

  6. HDU 6194 后缀数组

    string string string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  7. Qt ------ QElapsedTimer 计算消耗多少时间

    The QElapsedTimer class provides a fast way to calculate elapsed times. The QElapsedTimer class is u ...

  8. ACE服务端编程2:ACE跨平台之数据类型和宽字符

    ACE网络库的主要优势之一就是跨平台,ACE提供了操作系统API和编译器级别的跨平台解决方法,使开发人员不用再去关心操作系统和编译器的差异,但因此也带来了ACE的复杂性. ACE网络库的组织结构主要分 ...

  9. Maven仓库--Nexus的配置使用

    一.Nexus的作用 指定私服的中央地址.将自己的Maven项目指定到私服地址.从私服下载中央库的项目索引.从私服仓库下载依赖组件.将第三方项目jar上传到私服供其他项目组使用. 二.Nexus仓库 ...

  10. Tensorflow BatchNormalization详解:4_使用tf.nn.batch_normalization函数实现Batch Normalization操作

    使用tf.nn.batch_normalization函数实现Batch Normalization操作 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 吴恩达deeplearnin ...