HDU - 3085 双向BFS + 技巧处理 [kuangbin带你飞]专题二
题意:有两只鬼,一个男孩女孩被困在迷宫中,男孩每秒可以走三步,女孩只能1步,鬼可以两步且可以通过墙。问男孩女孩是否可以在鬼抓住他们之前会合?
注意:每秒开始鬼先移动,然后两人开始移动。
思路:以男孩和女孩为起点进行双向bfs,鬼由于可以穿墙可以直接通过曼哈顿距离判断当前位置是否合法。注意在处理男孩移动的时,必须加入一点技巧,否则处理状态太多就会超时。我用的一种比较笨的方法处理男孩的移动结果TLE了。
AC代码: 405ms
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
using namespace std;
const int maxn = 800 + 5;
char G[maxn][maxn];
int vis[2][maxn][maxn];
int n, m;
struct node{
int x, y;
node() {
}
node(int x, int y): x(x), y(y){
}
};
const int dx[] = {0,0,-1,1};
const int dy[] = {-1,1,0,0};
bool is_ghost(int x, int y, int step, vector<node> &p) {
for(int i = 0; i < p.size(); ++i) {
int px = p[i].x, py = p[i].y;
int man = abs(x - px) + abs(y - py); //曼哈顿距离
if(step * 2 >= man) return false;
}
return true;
}
queue<node>q[2];
vector<node>per, ghost;
int bfs(int c, int step) { //共有四个起点
int num = q[c].size();
while(num--) { //清空上一次的移动位置
node p = q[c].front();
q[c].pop();
int x = p.x, y = p.y;
if(!is_ghost(x, y, step + 1, ghost)) continue;
for(int i = 0; i < 4; ++i) {
int px = x + dx[i], py = y + dy[i];
if(px < 0 || py < 0 || px >= n || py >= m) continue;
if(vis[c][px][py] || G[px][py] == 'X' || !is_ghost(px, py, step + 1, ghost)) continue;
if(vis[1 - c][px][py]) return 1; //找到对方
q[c].push(node(px, py));
vis[c][px][py] = 1;
}
}
return 0;
}
int solve() {
per.clear();
ghost.clear();
while(!q[0].empty()) q[0].pop();
while(!q[1].empty()) q[1].pop();
memset(vis, 0, sizeof(vis));
for(int i = 0; i < n; ++i)
for(int j = 0; j < m; ++j) {
if(G[i][j] == 'M') {
per.push_back(node(i, j));
vis[0][i][j] = 1;
q[0].push(node(i, j));
}
else if(G[i][j] == 'G') {
per.push_back(node(i, j));
q[1].push(node(i, j));
vis[1][i][j] = 1;
}
else if(G[i][j] == 'Z') {
ghost.push_back(node(i, j));
}
}
for(int i = 0; i < 2; ++i) {
if(!is_ghost(per[i].x, per[i].y, 1, ghost)) return -1;
}
int step = -1;
while(!q[0].empty() && !q[1].empty()) {
++step;
for(int i = 0; i < 3; ++i) {
if(bfs(0, step)) return step + 1;
}
if(bfs(1, step)) return step + 1;
}
return -1;
}
int main() {
int T;
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; ++i) scanf("%s", G[i]);
printf("%d\n", solve());
}
return 0;
}
如有不当之处欢迎指出!
HDU - 3085 双向BFS + 技巧处理 [kuangbin带你飞]专题二的更多相关文章
- HDU - 3567 Eight II (bfs预处理 + 康托) [kuangbin带你飞]专题二
类似HDU1430,不过本题需要枚举X的九个位置,分别保存状态,因为要保证最少步数.要保证字典序最小的话,在扩展节点时,方向顺序为:down, left, right, up. 我用c++提交1500 ...
- HDU - 3567 IDA* + 曼哈顿距离 + 康托 [kuangbin带你飞]专题二
这题难度颇大啊,TLE一天了,测试数据组数太多了.双向广度优先搜索不能得到字典序最小的,一直WA. 思路:利用IDA*算法,当前状态到达目标状态的可能最小步数就是曼哈顿距离,用于搜索中的剪枝.下次搜索 ...
- 【算法系列学习三】[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 反向bfs打表和康拓展开
[kuangbin带你飞]专题二 搜索进阶 之 A-Eight 这是一道经典的八数码问题.首先,简单介绍一下八数码问题: 八数码问题也称为九宫问题.在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的 ...
- HDU - 3533 bfs [kuangbin带你飞]专题二
看了好久的样例才看懂. 题意:有一个人要从(0,0)走到(n,m),图中有k个碉堡,每个碉堡可以向某个固定的方向每隔t秒放一次炮,炮弹不能穿越另一个碉堡,会被阻挡.人在移动的过程中不会被炮弹打到,也就 ...
- HDU - 1067 Gap (bfs + hash) [kuangbin带你飞]专题二
题意: 起初定28张卡牌的排列,把其中11, 21, 31, 41移动到第一列,然后就出现四个空白,每个空白可以用它的前面一个数的下一个数填充,例如43后面的空格可以用44填充,但是47后面即 ...
- HDU - 2102 A计划 (BFS) [kuangbin带你飞]专题二
思路:接BFS判断能否在限制时间内到达公主的位置,注意如果骑士进入传送机就会被立即传送到另一层,不会能再向四周移动了,例如第一层的位置(x, y, 1)是传送机,第二层(x, y, 2)也是传送机,这 ...
- 【算法系列学习】[kuangbin带你飞]专题二 搜索进阶 D - Escape (BFS)
Escape 参考:http://blog.csdn.net/libin56842/article/details/41909459 [题意]: 一个人从(0,0)跑到(n,m),只有k点能量,一秒消 ...
- HDU - 1043 A* + 康托 [kuangbin带你飞]专题二
这题我第一次用的bfs + ELFhash,直接TLE,又换成bfs + 康托还是TLE,5000ms都过不了!!我一直调试,还是TLE,我才发觉应该是方法的问题. 今天早上起床怒学了一波A*算法,因 ...
- POJ - 3126 bfs + 素数筛法 [kuangbin带你飞]专题一
题意:给定两个四位素数作为终点和起点,每次可以改变起点数的某一位,且改变后的数仍然是素数,问是否可能变换成终点数字? 思路:bfs搜索,每次改变四位数中的某一位.素数打表方便判断新生成的数是否是素数. ...
随机推荐
- python初识 - day4
一.集合(set) 1.集合的定义 set 是一个无序的元素集合,支持并.交.差及对称差等数学运算, 但由于 set 不记录元素位置, 因此不支持索引.分片等类序列的操作. 2.集合的创建 大括号或 ...
- C# 值类型,引用类型区别
值类型/引用类型 作为所有类型的基类,System.Object提供了一组方法,这些方法在所有类型中都能找到,其中包含toString方法及clone等方法. 引用类型和值类型都继承自System.O ...
- awk说明书(转)
ref:http://blog.chinaunix.net/uid-429659-id-122573.html awk使用手册 作者:awk使用手册什么是awk? 你可能对UNIX比较熟悉,但你可能对 ...
- SpringMVC 参数绑定注解解析
本文介绍了用于参数绑定的相关注解. 绑定:将请求中的字段按照名字匹配的原则填入模型对象. SpringMVC就跟Struts2一样,通过拦截器进行参数匹配. 代码在 https://github.co ...
- Python之数据结构基础
一.数据结构基础 a.什么是数据结构 b.数据结构的分类 c.列表 import random from timewrap import ...
- H5WebSocket消息推送
1.效果图 2.前端代码 @{ ViewBag.Title = "Home Page"; } @*HTML5 WebSocket WebSocket是HTML5开始提供的一种在单个 ...
- canvas将图片转为base64
最简例子 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta ...
- JAVA设计模式之---工厂模式
1.引言 工厂模式可以分为类: 1)简单工厂模式(Simple Factory) 2)工厂方法模式(Factory Method) 3)抽象工厂模式(Abstract Factory) 这种模式从上 ...
- 10_set集合
一.集合类型 集合是一组无序排列的可哈希的值(可哈希的值->不可变),集合成员可以做字典中的键.但集合本身是不可哈希的. 集合是无序没有索引,也没有像字典的key,所以集合不能更改元素.只能增删 ...
- java配置context.xml文件
2018-02-08 23:32:23 修改context.xml文件 自从学习了servlet后,每次修改里面的内容后,想要访问都要重启服务器,这样感觉很麻烦的,所以今天就教大家一个方法,只需要 ...