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 ...
随机推荐
- centos7 下安装和配置 mongodb (重点)
1.下载安装包 wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.0.4.tgz 2.解压 tar -zxvf m ...
- mysql数据库引擎——MyISAM,InnoDB
作为一个java web开发人员,对于mysql数据库掌握到具体比较这两类引擎的差异也蛮拼的,下面就介绍一下我在工作中积累的对这两类引擎的理解. MyISAM: 如果不更改mysql配置文件(my.i ...
- Android Dalvik、ART及APK编译过程
0.1 先对Dalvik以及ART做简单介绍: 什么是Dalvik: Dalvik是Google公司自己设计用于Android平台的Java虚拟机.dex格式是专为Dalvik应用设计的一种压缩格式, ...
- PhoneUtils
import java.util.regex.Matcher; import java.util.regex.Pattern; public class PhoneUtils { /** * @par ...
- Python异步IO之协程(二):使用asyncio的不同方法实现协程
引言:在上一章中我们介绍了从yield from的来源到async的使用,并在最后以asyncio.wait()方法实现协程,下面我们通过不同控制结构来实现协程,让我们一起来看看他们的不同作用吧- 在 ...
- ssm整合用到的web.xml配置
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns ...
- 【C# in depth 第三版】温故而知新(1) (转)
声明 本文欢迎转载,原文地址:http://www.cnblogs.com/DjlNet/p/7192354.html 前言 关于这本书(<深入理解C# 第三版>)的详细情况以及好坏,自行 ...
- centos7安装kvm及kvm管理
一.安装kvm 查看CPU是否支持虚拟化 grep -E 'svm|vmx' /proc/cpuinfo - vmx is for Intel processors - svm is for AMD ...
- 上传NUnit的单元测试结果和OpenCover的单元测试覆盖率到SonarQube服务中
SonarQube.Scanner.MSBuild.exe begin /k:"OMDCCQuotes" /d:sonar.host.url="http://myip:9 ...
- go http server 编程
第一种:最简单的 package main import ( "fmt" "log" "net/http" ) func myHandler ...