HDU3085NightmareII题解--双向BFS
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=3085
分析
大意就是一个男孩和一个女孩在网格里,同时还有两个鬼,男孩每轮走三步,女孩每轮走一步,与鬼曼哈顿距离不超过2*轮数的区域都被鬼占领,问男孩女孩最少多少轮相遇?
这题显然用双向BFS,男孩每轮拓展3次,女孩每轮拓展1次,一个记录女孩走过哪些地方,另一个记录男孩,有个地方被两人都走过就输出答案
然后一开始我就发现我的BFS写得代码又臭又长,后面看一位大佬博客才学到简洁的操作
代码
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <iostream>
#define ll long long
#define ri register int
using std::min;
using std::max;
using std::swap;
using std::queue;
template <class T>inline int abs(int x){
return x<0?-x:x;
}
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c=='-';
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int maxn=805;
const int inf=0x7fffffff;
const int dx[4]={-1,1,0,0},dy[4]={0,0,-1,1};
int g[maxn][maxn];
int n,m,T;
int sx,sy,tx,ty;
int gx1,gx2,gy1,gy2;
char str[maxn];
struct Dat{
int x,y;
Dat (int _x,int _y){x=_x,y=_y;}
Dat () {x=y=0;}
};
int cnt=1,dis;
bool wtf=0;
bool vis1[maxn][maxn],vis2[maxn][maxn];
bool check(int x,int y){
//if(wtf)printf("** %d %d %d %d %d %d\n",x,y,cnt,dis,abs(x-gx1)+abs(y-gy1),abs(x-gx2)+abs(y-gy2));
if(x>=1&&x<=n&&y>=1&&y<=m&&g[x][y]!=1&&(abs(x-gx1)+abs(y-gy1))>dis&&(abs(x-gx2)+abs(y-gy2))>dis)return 1;
return 0;
}
inline void bfs(){
int x,y,xx,yy;
int x1,x2,x3,y1,y2,y3,x4,y4;
queue <Dat> q1,q2;
while(q1.size())q1.pop();
while(q2.size())q2.pop();
q1.push(Dat(sx,sy));
q2.push(Dat(tx,ty));
cnt=1,dis=2;
int l1=1,r1=1,l2=1,r2=1,lst=0;
memset(vis1,0,sizeof(vis1));
memset(vis2,0,sizeof(vis2));
vis1[sx][sy]=vis2[tx][ty]=1;
while(q1.size()&&q2.size()){wtf=0;
for(ri k=1;k<=3;k++){
lst=r1;
while(l1<=lst){
x=q1.front().x,y=q1.front().y;q1.pop();
l1++;
if(!check(x,y))continue;
//printf("1 %d %d\n",x,y);
for(ri i=0;i<4;i++){
xx=x+dx[i],yy=y+dy[i];
if(!check(xx,yy)||vis1[xx][yy])continue;
q1.push(Dat(xx,yy));
if(vis2[xx][yy]){
//printf("--%d %d %d\n",cnt,xx,yy);
printf("%d\n",cnt);
return ;
}
vis1[xx][yy]=1;
r1++;
}
}
}
lst=r2;wtf=1;
while(l2<=lst){
x=q2.front().x,y=q2.front().y;q2.pop();//printf("%d %d\n",l2,lst);
l2++;
if(!check(x,y))continue;
for(ri i=0;i<4;i++){
xx=x+dx[i],yy=y+dy[i];
if(!check(xx,yy)||vis2[xx][yy])continue;
q2.push(Dat(xx,yy));//printf("2 %d %d\n",xx,yy);
if(vis1[xx][yy]){
printf("%d\n",cnt);
return ;
}
vis2[xx][yy]=1;
r2++;
}
//printf("*** %d %d %d\n",l2,r2,lst);
}
cnt++;
dis=cnt*2;
}
puts("-1");
return ;
}
int main(){
read(T);
while(T--){
read(n),read(m);
gx1=gy1=inf;
for(ri i=1;i<=n;i++){
scanf("%s",str+1);
for(ri j=1;j<=m;j++){
vis1[i][j]=0,vis2[i][j]=0;
if(str[j]=='.')g[i][j]=0;
else if(str[j]=='X')g[i][j]=1;
else if(str[j]=='M'){
g[i][j]=2;
sx=i,sy=j;
}
else if(str[j]=='G'){
g[i][j]=3;
tx=i,ty=j;
}
else if(str[j]=='Z'){
if(gx1==inf)gx1=i,gy1=j;
else gx2=i,gy2=j;
}
}
}
//printf("%d %d %d %d %d %d %d %d\n",sx,sy,tx,ty,gx1,gy1,gx2,gy2);
bfs();
}
return 0;
}
HDU3085NightmareII题解--双向BFS的更多相关文章
- HDU3085(双向BFS+曼哈顿距离)题解
Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- HDU 6171 Admiral(双向BFS+队列)题解
思路: 最大步骤有20,直接BFS会超时. 因为知道开始情况和结果所以可以用双向BFS,每个BFS规定最大步骤为10,这样相加肯定小于20.这里要保存每个状态搜索到的最小步骤,用Hash储存.当发现现 ...
- [题解](双向bfs)hdu_3085_Nightmare Ⅱ
发现直接搜索比较麻烦,但是要同时两个人一起走容易想到双向bfs,比较普通, 在判断是否碰到ghost时只要比较两点的曼哈顿距离大小和step*2(即ghost扩散的距离)即可,仔细思考也是可以想到的 ...
- HDU 3085 Nightmare Ⅱ 双向BFS
题意:很好理解,然后注意几点,男的可以一秒走三步,也就是三步以内的都可以,鬼可以穿墙,但是人不可以,鬼是一次走两步 分析:我刚开始男女,鬼BFS三遍,然后最后处理答案,严重超时,然后上网看题解,发现是 ...
- UVA1601-The Morning after Halloween(双向BFS)
Problem UVA1601-The Morning after Halloween Accept: 289 Submit: 3136 Time Limit: 12000 mSec Problem ...
- 【bzoj5049】[Lydsy九月月赛]导航系统 并查集+双向BFS最短路
题目描述 给你一张 $n$ 个点 $m$ 条边的随机图,边权为1.$k$ 次询问两点间最短路,不连通则输出-1. 输入 第一行包含3个正整数n,m,k(2<=n<=100000,1< ...
- HDU——1195Open the Lock(双向BFS)
Open the Lock Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- HDU3085 Nightmare Ⅱ —— 双向BFS + 曼哈顿距离
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Other ...
- CSUOJ2031-Barareh on Fire(双向BFS)
Barareh on Fire Submit Page Description The Barareh village is on fire due to the attack of the virt ...
随机推荐
- mapReduce的优化-combiner
mr的合成器,本质上就是reduce,在map端执行,称之为map端reduce,或者预聚合. 例子: job.setCombinerClass(WordCountCombiner.class);
- 自定义 TreeView 第三种状态(C#自定义控件)
本文核心部分采用 http://blog.csdn.net/am2004/article/details/1621349 此网站代码. 在增加了部份事件的同时,将点击图片更改节点选中状态 这一小地方作 ...
- linux下如何映射宿主机中的文件到容器中?
答:在启动容器时使用-v指定宿主机目录和要映射到的容器内部目录,语法如下: docker run -it -v <host_dir>:<container_dir> <c ...
- known
邻接表 https://blog.csdn.net/Violet_ljp/article/details/80556460 Dijkstra 算法实现原理 https://www.jianshu.co ...
- CSS 背景色变化 结构化伪类的练习
CSS3的nth-child() 选择器(兼容性不好),在做表格偶数行变色的时候,我通常在绑定的时候,做一个js判断,来加一个css,从而使表格偶数行和奇数行颜色不一样.这样的兼容性很好. 但是最近在 ...
- python用cx_Oracle连接oracle
确认版本: oracle版本:64位 python版本:64位 下载cx_Oracle的whl包:64位 安装whl包:pip install wheel cd到下载路径安装cx_Oracle的whl ...
- Swift 3.0 闭包的定义和使用
// // ViewController.swift // 闭包的定义和使用 // // Created by 思 彭 on 16/9/17. // Copyright © 2016年 思 彭. Al ...
- pageoffice实现网页打开编辑保存word文档(基于SSM框架)
pageoffice是一款网页集成word.excel...等office工具 并不免费,但可以试用练习 SSM框架搭建过程就省略了 注意:由于谷歌/火狐升级,不支持插件嵌入,建议使用POBrowse ...
- pandas中对日期型数据进行处理
因为数据不方便展示,直接上代码. 将字符串转为datetime64[ns]格式: pd.to_datetime('2019-12-20') or pd.to_datetime('20191220') ...
- 【计算机视觉】Vibe Vibe+
ViBe是一种像素级的背景建模.前景检测算法,该算法主要不同之处是背景模型的更新策略,随机选择需要替换的像素的样本,随机选择邻域像素进行更新.在无法确定像素变化的模型时,随机的更新策略,在一定程度上可 ...