HDU3085_Nightmare Ⅱ_双向BFS
来源:互联网 发布:朱宸慧淘宝店经历 编辑:程序博客网 时间:2024/06/08 11:31
题意
在一个迷宫里,有一个boy和一个girl,还有两个鬼。boy每秒钟走 3 步,girl 每秒钟走 1 步,鬼每秒钟超两步内能到达的格内分身。注意,鬼可以无视墙壁。并且, 每一秒,鬼分裂boy和girl再走。如果boy或girl和鬼在一个格子里,它们会被吃掉。问在被吃掉之前boy和girl能否相遇。
思路
一开始想的是 预处理+BFS。就是先把 鬼 和 boy 到达每个点的时间求出来,然后对 girl BFS。果不其然,TLE。这个题是 双向BFS。
1.从 boy 和 girl 两个点出发,双向BFS。
2.不需要对 鬼 进行预处理,只需在到达每个点是判断点到鬼的距离即可,O(1)。
3.需要注意的一点是,输入的时候如果一个字符一个字符地读会TLE,一行一行地读就AC了。
双向DFS
其实双向dfs就是把 队列 和 dis 数组都搞成二维的,对应每一方向。然后把起点和终点分别放进一个队列里,当两个队列出现重合点时,搜索就结束了。
双向DFS较单向有很大幅度的效率提升。
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=3085
AC代码
#include<cstdio>#include<iostream>#include<cstring>#include<queue>using namespace std;typedef pair<int, int> P;const int maxn = 810;const int inf = 0x3f3f3f3f;const int mx[4] = {-1, 0, 1, 0};const int my[4] = {0, 1, 0, -1};int cas;int n, m;char G[maxn][maxn];P M, W, Z0, Z1;bool dis[2][maxn][maxn];queue<P> qu[2];int Abs(int x){ return x > 0 ? x : -x;}//检查点是不是安全bool check(int x, int y, int steps){ if(x < 0 || x >= n || y < 0 || y >= m) return false; if(G[x][y] == 'X') return false; //和鬼的距离 if(Abs(x - Z0.first) + Abs(y - Z0.second) <= 2 * steps) return false; if(Abs(x - Z1.first) + Abs(y - Z1.second) <= 2 * steps) return false; return true;}//u 是队列序号,steps 是时间bool bfs(int u, int steps){ int num = qu[u].size();//这一点学到了 while(num --) { int x = qu[u].front().first, y = qu[u].front().second; qu[u].pop(); if(!check(x, y, steps)) continue;//因为鬼先走,所以这里还要检查一次 for(int i= 0; i< 4; i++) { int xx = x + mx[i], yy = y + my[i]; if(!dis[u][xx][yy] && check(xx, yy, steps)) { if(dis[u^1][xx][yy]) return true;//会师成功 dis[u][xx][yy] = true; qu[u].push(P(xx, yy)); } } } return false;}int bid_bfs(){ //初始化 memset(dis, false, sizeof dis); while(qu[0].size()) qu[0].pop(); while(qu[1].size()) qu[1].pop(); //两个起点各自入队 dis[0][M.first][M.second] = true; qu[0].push(M); dis[1][W.first][W.second] = true; qu[1].push(W); //boy 走三步,girl 走一步 for(int i= 1; qu[0].size() || qu[1].size(); i++) { if(bfs(0, i)) return i; if(bfs(0, i)) return i; if(bfs(0, i)) return i; if(bfs(1, i)) return i; } //不能会师 return -1;}int main(){ cin >> cas; while(cas --) { scanf("%d %d", &n, &m); for(int i= 0; i< n; i++) scanf(" %s", &G[i]); Z0.first = -1; for(int i= 0; i< n; i++) for(int j= 0; j< m; j++) { if(G[i][j] == 'M') M = P(i, j); if(G[i][j] == 'G') W = P(i, j); if(G[i][j] == 'Z') if(Z0.first == -1) Z0 = P(i, j); else Z1 = P(i, j); } cout << bid_bfs() << endl; } return 0;}
阅读全文
0 0
- HDU3085_Nightmare Ⅱ_双向BFS
- BFS:HDU3085-Nightmare Ⅱ(双向BFS)
- HDU3085 Nightmare Ⅱ[双向bfs]
- HDU3085 Nightmare Ⅱ 双向bfs
- hdu3085 Nightmare Ⅱ【双向BFS】
- 双向BFS
- 双向BFS
- 双向BFS
- 双向BFS
- 双向BFS
- 双向BFS
- POJ1915 BFS&双向BFS
- hdu 3085 Nightmare Ⅱ (双向bfs)
- HDU-3085-Nightmare Ⅱ(双向BFS)
- HDU 3081 Nightmare Ⅱ(双向BFS)
- hdu 3085 Nightmare Ⅱ(双向bfs)
- HDU 3085 Nightmare Ⅱ(双向BFS)
- HDU 3085 Nightmare Ⅱ(双向BFS)
- 南阳理工acm 1070诡异的电梯【Ⅰ】(动态规划)
- 伪分布安装Hadoop2.8.0+Hbase1.3.1+Hive1.2.1+Kylin2.0
- 单周期CPU实验
- 设计原则--面向对象
- Maven中后台管理工程的搭建
- HDU3085_Nightmare Ⅱ_双向BFS
- Spring Batch 环境设置
- 在软帝的第二天
- 计算机网络读书笔记——物理层(1)
- VS2015中运行32位汇编程序
- redis主从配置及高可用哨兵
- Canvas学习笔记之画圆(笑脸)
- 第一场个人训练赛——E-成绩转换(HDU 2004)
- 反转链表(在原链表进行操作,不开辟新空间. O(N)