【HDU - 3085】Nightmare Ⅱ(bfs)
-->Nightmare Ⅱ
原题太复杂,直接简单的讲中文吧
Descriptions:
X表示墙
.表示路
M,G表示两个人
Z表示鬼
M要去找G但是有两个鬼(Z)会阻碍他们,每一轮都是M和G先走M能走3步,G能走1步,Z每次向边上2步内变出分身。求所需最短时间。
鬼能穿墙,人不能
Sample Input
- 3
- 5 6
- XXXXXX
- XZ..ZX
- XXXXXX
- M.G...
- ......
- 5 6
- XXXXXX
- XZZ..X
- XXXXXX
- M.....
- ..G...
- 10 10
- ..........
- ..X.......
- ..M.X...X.
- X.........
- .X..X.X.X.
- .........X
- ..XX....X.
- X....G...X
- ...ZX.X...
- ...Z..X..X
Sample Output
- 1
- 1
- -1
题目链接:
https://vjudge.net/problem/HDU-3085
设step为人一共走的轮数,每轮M走3步,G走1步,Z走2步
假设第step轮M、G碰面,碰面的地方为tmp,两个鬼为 zz[i],i可以是0或1表示两个鬼的编号,设横纵坐标分别为x,y
则tmp和zz[i]的距离为
abs(tmp.x-zz[i].x)+abs(tmp.y-zz[i].y) 这个即是曼哈顿距离
鬼在step轮可以走2*step步
若 abs(tmp.x-zz[i].x)+abs(tmp.y-zz[i].y)<=2*step
那就表示这个地方鬼能来,则这个地方不能碰面
相反若 abs(tmp.x-zz[i].x)+abs(tmp.y-zz[i].y)>2*step
那就表示这个地方鬼不能来,则这个地方能碰面
具体操作见代码
AC代码
- #include <iostream>
- #include <cstdio>
- #include <fstream>
- #include <algorithm>
- #include <cmath>
- #include <deque>
- #include <vector>
- #include <queue>
- #include <string>
- #include <cstring>
- #include <map>
- #include <stack>
- #include <set>
- #include <sstream>
- #define mod 1000000007
- #define eps 1e-6
- #define ll long long
- #define INF 0x3f3f3f3f
- #define MEM(x,y) memset(x,y,sizeof(x))
- #define Maxn 1000
- using namespace std;
- int T,n,m;
- int step;//走了几轮
- char mp[Maxn][Maxn];//原始地图
- int dt[][]= {{,},{-,},{,},{,-}};//四个方向
- struct node
- {
- int x,y;//坐标
- };
- node now,net;
- node zz[],mm,gg;//鬼 M G
- queue<node>q[];//分别表示队列M和G
- queue<node>qt;//后面函数要用到,过渡
- bool judge(node tmp)
- {
- for(int i=; i<; i++)
- {
- if(abs(tmp.x-zz[i].x)+abs(tmp.y-zz[i].y)<=step*||mp[tmp.x][tmp.y]=='X'||mp[tmp.x][tmp.y]=='\0')
- return false;
- }
- return true;
- }
- bool bfs(int pos,int steps,char start,char endd)//队列的编号 M或G可以走的步数 开始标志 结束标志
- {
- qt=q[pos];//替代,后面要根据不同的steps进行走路
- for(int j=; j<steps; j++)//这一轮走几步
- {
- while(!qt.empty())
- {
- now=qt.front();
- qt.pop();
- q[pos].pop();
- if(!judge(now))//不满足
- continue;
- for(int i=; i<; i++)//四个方向
- {
- net.x=now.x+dt[i][];
- net.y=now.y+dt[i][];
- if(!judge(net)||mp[net.x][net.y]==start)
- continue;
- if(mp[net.x][net.y]==endd)//M找到G或G找到M
- return true;
- mp[net.x][net.y]=start;//将走过的地方表示为开始标志,即M或G已经来过这
- q[pos].push(net);
- }
- }
- qt=q[pos];//都向外走了一步,重新初始化qt,再向外走一步
- }
- return false;
- }
- int solve()
- {
- step=;//初始化
- while(!q[].empty())//初始化队列,清空
- q[].pop();
- while(!q[].empty())
- q[].pop();
- while(!qt.empty())
- qt.pop();
- q[].push(mm);//分别入队
- q[].push(gg);
- while(!q[].empty()&&!q[].empty())
- {
- step++;//走了几轮
- if(bfs(,,'M','G')||bfs(,,'G','M'))
- return step;
- }
- return -;
- }
- int main()
- {
- scanf("%d",&T);//这里都要用scanf和printf,不然会超时
- while(T--)
- {
- scanf("%d%d",&n,&m);
- MEM(mp,'X');//把地图初始化为X
- for(int cnt=,i=; i<=n; i++)
- {
- scanf("%s",&mp[i][]);//一行一行存地图
- for(int j=; j<=m; j++)
- {
- // scanf("%c",&mp[i][j]);
- // cin>>mp[i][j];
- if(mp[i][j]=='M')
- {
- mm.x=i;
- mm.y=j;
- }
- if(mp[i][j]=='G')
- {
- gg.x=i;
- gg.y=j;
- }
- if(mp[i][j]=='Z')
- {
- zz[cnt].x=i;
- zz[cnt].y=j;
- cnt++;
- }
- }
- }
- printf("%d\n",solve());
- }
- }
【HDU - 3085】Nightmare Ⅱ(bfs)的更多相关文章
- 【HDU - 3533】Escape(bfs)
Escape Descriptions: 一个人从(0,0)跑到(n,m),只有k点能量,一秒消耗一点,在图中有k个炮塔,给出炮塔的射击方向c,射击间隔t,子弹速度v,坐标x,y问这个人能不能安全到 ...
- 【HDU 3085】 Nightmare Ⅱ
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3085 [算法] 双向BFS [代码] #include<bits/stdc++.h> ...
- 【HDU 2853】Assignment (KM)
Assignment Problem Description Last year a terrible earthquake attacked Sichuan province. About 300, ...
- 【POJ - 3414】Pots(bfs)
Pots 直接上中文 Descriptions: 给你两个容器,分别能装下A升水和B升水,并且可以进行以下操作 FILL(i) 将第i个容器从水龙头里装满(1 ≤ i ≤ 2); DRO ...
- 【Aizu - 0558】Cheese(bfs)
-->Cheese 原文是日语,这里就写中文了 Descriptions: 在H * W的地图上有N个奶酪工厂,每个工厂分别生产硬度为1-N的奶酪.有一只老鼠准备从出发点吃遍每一个工厂的奶酪.老 ...
- 【HDU - 4345 】Permutation(DP)
BUPT2017 wintertraining(15) #8F 题意 1到n的排列,经过几次置换(也是一个排列)回到原来的排列,就是循环了. 现在给n(<=1000),求循环周期的所有可能数. ...
- 【HDU 6005】Pandaland(Dijkstra)
Problem Description Mr. Panda lives in Pandaland. There are many cities in Pandaland. Each city can ...
- 【HDU - 6581】Vacation(思维)
Vacation 题意 有n+1辆车,属性有长度l,距离终点的距离s,速度v问你最末尾的车到达终点的时间 Sample Input 1 2 2 7 1 2 1 2 1 2 2 10 7 1 6 2 1 ...
- 【HDU 5750】Dertouzos(数学)
题目给定n和d,都是10的9次方以内,求1到n里面有几个数最大因数是d?1000000组数据.解:求出d的满足p[i]*d<n的最小质因数是第几个质数.即为答案. #include<cst ...
随机推荐
- VoIP应用在Ubuntu 14.04下编译FFmpeg libX264及PJSIP
PJSIP是一个开源的SIP协议栈.它支持多种SIP的扩展功能,可说算是最目前流行的SIP协议栈之一了. 它实现了SIP.SDP.RTP.STUN.TURN和ICE.PJSIP作为基于SIP的一个多 ...
- RDIFramework.NET框架SOA解(集Windows服务、WinForm形式和IIS发布形式)-分布式应用程序
RDIFramework.NET框架SOA解决方式(集Windows服务.WinForm形式与IIS形式公布)-分布式应用 RDIFramework.NET,基于.NET的高速信息化系统开发.整合框架 ...
- JAVASCRIPT高程笔记-------第五章 引用类型
一.Object类型 1.1创建方式 ①new关键字 : var person = new Oject(); ②给定直接量: var person = { name : "zhangsan& ...
- fatal error LNK1169:找到一个或多个重定义的符号
这个算是个比较基础的问题,由于我不是C程序员,本行java,临时拉来做的,所以有些坑还得自己走出来. 这个问题是由于,全局变量在a.h中定义,在两个源文件a.cpp和b.cpp中引用,之后被编译器认为 ...
- UWP-电子音读出文字
原文:UWP-电子音读出文字 源码: https://github.com/lindexi/Markdown 代码 private async void speech(string str, Medi ...
- 仿win7窗体自动顶部最大化左侧右侧半屏效果(改写nativeEvent,使用AdjustWindowRectEx)
#include "HMainWindow.h" #include <QApplication> #ifdef Q_OS_WIN #include <qt_win ...
- 想让一个Widget成为模态,我们只需要对其设置setAttribute(Qt::WA_ShowModal, true);
想让一个Widget成为模态,我们只需要对其设置: setAttribute(Qt::WA_ShowModal, true); 注意:这是QWidget的成员函数 ,也就是说,QWidget可以显示为 ...
- Flot Reference flot参考文档
Consider a call to the plot function:下面是对绘图函数plot的调用: var plot = $.plot(placeholder, data, options) ...
- Qt for android触摸手势事件QGestureEvent
在触摸设备上可以使用Qt的手势事件 要激活手势事件,需要执行以下操作: 第一步,为QWidget控件注册手势事件 QList<Qt::GestureType> gestures; gest ...
- delphi中move函数的正确理解(const和var一样,都是传地址,所以Move是传地址,而恰恰不是传值)太精彩了 good
我们能看到以下代码var pSource,pDest:PChar; len: integer;.......................//一些代码Move(pSource,pDest,l ...