HDU3085 Nightmare Ⅱ[双向bfs]

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情


D - Nightmare Ⅱ
Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

Description

Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were trapped in a big maze separately. More terribly, there are two ghosts in the maze. They will kill the people. Now little erriyue wants to know if he could find his girl friend before the ghosts find them. 
You may suppose that little erriyue and his girl friend can move in 4 directions. In each second, little erriyue can move 3 steps and his girl friend can move 1 step. The ghosts are evil, every second they will divide into several parts to occupy the grids within 2 steps to them until they occupy the whole maze. You can suppose that at every second the ghosts divide firstly then the little erriyue and his girl friend start to move, and if little erriyue or his girl friend arrive at a grid with a ghost, they will die. 
Note: the new ghosts also can devide as the original ghost. 
 

Input

The input starts with an integer T, means the number of test cases. 
Each test case starts with a line contains two integers n and m, means the size of the maze. (1<n, m<800) 
The next n lines describe the maze. Each line contains m characters. The characters may be: 
‘.’ denotes an empty place, all can walk on. 
‘X’ denotes a wall, only people can’t walk on. 
‘M’ denotes little erriyue 
‘G’ denotes the girl friend. 
‘Z’ denotes the ghosts. 
It is guaranteed that will contain exactly one letter M, one letter G and two letters Z. 
 

Output

Output a single integer S in one line, denotes erriyue and his girlfriend will meet in the minimum time S if they can meet successfully, or output -1 denotes they failed to meet.
 

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
 

题意:

看M和G能不能在不遇到鬼的情况下,找到对方.

M一次可以走三步 G只能走一步 鬼可以走两步 



貌似用优先队列改了队列里面的顺序..不能用
改成队列就过了.

完全不知道为什么..不管了..

M的三步我用了一个leave去保存, 从0-2 到了2之后 就把该点的步数加一 放在队列里面

其余的 记得先比较跟鬼的距离,因为鬼是先走的,当前点如果和鬼的曼哈顿距离 小于2*step的话 , 就不能用该点 continue






#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<vector>
using namespace std;
const int N=810;
int n,m;
char Map[N][N];
bool mark[N][N][2],flag,used[N][N];
int dir[4][2]={{-1,0},{0,1},{1,0},{0,-1}};
struct node
{
    int x,y,step,leave;
}M,G,Z[2];
queue<node>q;
queue<node>p;
bool check(int x,int y,int num,int step)
{
    if (x<0 || x>=n || y<0 || y>=m || mark[x][y][num] || Map[x][y]=='X' || abs(x-Z[0].x)+abs(y-Z[0].y)<=2*step || abs(x-Z[1].x)+abs(y-Z[1].y)<=2*step)
        return 0;
    return 1;
}
bool check(int x,int y,int step)
{
    if (abs(x-Z[0].x)+abs(y-Z[0].y)<=2*step || abs(x-Z[1].x)+abs(y-Z[1].y)<=2*step)
        return 0;
    return 1;
}
int bfs()
{
    flag=0;
    while (!q.empty())
        q.pop();
    while (!p.empty())
        p.pop();
    q.push(M);
    p.push(G);
    int s=0;
    while (!q.empty() || !p.empty())
    {
        node start,later;
        while (!q.empty() && q.front().step<=s)
        {
            start=q.front();
            q.pop();
            if (!check(start.x,start.y,start.step+1))
                    continue;
            for (int i=0 ; i<4 ; i++)
            {
                int nx=start.x+dir[i][0];
                int ny=start.y+dir[i][1];
                if (check(nx,ny,0,start.step+1))
                {
                    if (mark[nx][ny][1])
                        return start.step+1;
                    mark[nx][ny][0]=1;
                    later.x=nx;
                    later.y=ny;
                    later.step=start.step;
                    if (start.leave==2)
                    {
                        later.leave=0;
                        later.step++;
                    }
                    else
                        later.leave=start.leave+1;
                    q.push(later);
                }
            }
        }
        while (!p.empty() && p.front().step<=s)
        {
            start=p.front();
            p.pop();
            if (!check(start.x,start.y,start.step+1))
                continue;
            for (int i=0 ; i<4 ; i++)
            {
                int nx=start.x+dir[i][0];
                int ny=start.y+dir[i][1];
                if (check(nx,ny,1,start.step+1))
                {
                    if (mark[nx][ny][0])
                        return start.step+1;
                    mark[nx][ny][1]=1;
                    later.x=nx;
                    later.y=ny;
                    later.step=start.step+1;
                    later.leave=start.leave;
                    p.push(later);
                }
            }
        }
        s++;
    }
    return -1;
}
int main()
{
    int T;
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&n,&m);
        memset(mark,0,sizeof(mark));
        int z=0;
        for (int i=0 ; i<n ; i++)
        {
            scanf("%s",Map[i]);
            for (int j=0 ; j<m ; j++)
            {
                if (Map[i][j]=='M')
                {
                    M.x=i;
                    M.y=j;
                    M.leave=0;
                    mark[i][j][0]=1;
                    M.step=0;
                }
                else if (Map[i][j]=='G')
                {
                    G.x=i;
                    G.y=j;
                    G.leave=0;
                    mark[i][j][1]=1;
                    G.step=0;
                }
                else if (Map[i][j]=='Z')
                {
                    Z[z].x=i;
                    Z[z].y=j;
                    Z[z++].step=0;
                }
            }
        }
        printf("%d\n",bfs());
    }
    return 0;
}



/*
5 6
XXXXXX
XZZ..X
XXXXXX
M.....
..G...
5 6
XXXXXX
XZZ..X
XXXXXX
M.....
.XG...
5 6
XXXXXX
XZZ..X
XXXXXX
MG....
.X....

5 6
XXXXXX
XZZ..X
XXXXXX
M.X...
XX.XG.

*/


HDU 3085 Nightmare Ⅱ(双向BFS 题意   A、B在迷宫中,A每回合能走3步,B每回合能走1步,迷宫中还有2个鬼,每回合最先活动,会向两步内的格子分裂,A、B不能碰鬼,求他们最快见面的回合数 思路 ​ 题目中描述A能走3步,实际上意思是A每回合能移动[0,3]步,B也同理,所以只要考虑A、B尽可能最远到达的区域,在当前回合这些区域内都是可达的   将整个题目可以考虑为一个像染色的模型,A、B、鬼分别以每回合3、1、2的速度染色,... 阅读详情

相关推荐

HDU 3085 Nightmare Ⅱ【双向bfs

Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3927    Accepted Submission(s): 1131   Problem Description Last night, little er...

Emiya丶的博客 578

Unable to read class [XXXXXXX]} java.lang. ArrayIndexOutOfBoundsException

Java代码 @Component public class FcmHelper { private static final Logger log = LoggerFactory.getLogger(FcmHelper.class); private static String APP_ID = ""; private static String SECRET_KEY = ""; private static String CHECK_URL = ""; pr.

YPC的博客 5983

字符集的选择

字符集的选择 一:背景介绍 DICOM特定字符集(0008,0005) 此标签获得不同的值就代表使用不同的语言进行解码。 以下为多家CT厂商的(0008,0005)取值: 字符集: unicode是字符集,ASCII、GB2312、GBK、GB18030既是字符集也是编码方式,UTF-8只是编码方式。 二:中文字符集介绍 世界通用字符集——UTF 中文字符集——GB2312、GBK、GB18030 字符集的详细介绍 一:UTF-8 程序是把一个字节一个字节的来读取,然后再根据字节中开头的bit

qq_41972968的博客 1500

xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

1.解压 tar zxvf wmsdk_bundle-xxxxxxx cd wmsdk_bundle-xxxxxxx 2. make installpkgs 3.安装gcc-arm-none-eabi http://blog.csdn.net/al86866365/article/details/47424727 4.编译测试 make boot2 5.下载 Error:

al86866365的专栏 87万+

噩梦

给定一张N*M的地图,地图中有1个男孩,1个女孩和2个鬼。 字符“.”表示道路,字符“X”表示墙,字符“M”表示男孩的位置,字符“G”表示女孩的位置,字符“Z”表示鬼的位置。 男孩每秒可以移动3个单位距离,女孩每秒可以移动1个单位距离,男孩和女孩只能朝上下左右四个方向移动。 每个鬼占据的区域每秒可以向四周扩张2个单位距离,并且无视墙的阻挡,也就是在第k秒后所有与鬼的曼哈顿距离不超过2k的位置都会被...

sky123博客 547

[转载]Smashing The Stack For Fun And Profit

[转载]Smashing The Stack For Fun And Profit .oO Phrack 49 Oo. Volume Seven, Issue Forty-Nine ...

weixin_30916125的博客 390

双向bfs——噩梦(模板)

思路:一眼丁真,鉴定为“春春的bfs”,使用两个队列分别存男孩和女孩的行动路径,注意与鬼之间的曼哈顿距离不要小于当前时间常数time乘2。

测试 319

双向bfs --HDU - 3085 Nightmare

HDU - 3085 Nightmare Ⅱ:https://vjudge.net/problem/HDU-3085 题意: G和M在迷宫里寻找对方,M每秒可以走3步,G每次走一步,且只能上下左右走。迷宫里有鬼,鬼每次分裂到上下左右两格位置,直到占满所有格子,鬼可以穿墙,求G和M在不遇到鬼的情况下的最短相遇时间。 思路: 双向bfs,由于M每次走3步,所以M每次要处理3次,这要处理的点就是M每次要...

dajiangyou123456的博客 188

HDU3085 - Nightmare Ⅱ(双向BFS

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085题目大意:在一个N*M的网格里,有两个人 G 和 M,并且有两只鬼。 G每秒可以走一步,G每秒可以走三步,每只鬼可以分裂,分裂到周围的的两格。假设#为鬼分裂后为1,如下图所示。每只分裂后的新鬼可以继续分裂。

ACM_Fish的博客 451

HDU3085 Nightmare双向BFS

题目描述 给定一张N*M的地图,地图中有1个男孩,1个女孩和2个鬼。 字符“.”表示道路,字符“X”表示墙,字符“M”表示男孩的位置,字符“G”表示女孩的位置,字符“Z”表示鬼的位置。 男孩每秒可以移动3个单位距离,女孩每秒可以移动1个单位距离,男孩和女孩只能朝上下左右四个方向移动。 每个鬼占据的区域每秒可以向四周扩张2个单位距离,并且无视墙的阻挡,也就是在第k秒后所有与鬼的曼哈顿距离不超过2k的...

正月看雪花的博客 550

HDU 3085 —— Nightmare双向BFS

原题:http://acm.hdu.edu.cn/showproblem.php?pid=3085 题意: ' X ' 表示墙;' . ' 表示空地;' Z ' 表示鬼(鬼有两只); M每秒走三步;G每秒走一步;鬼每秒分裂,每次分裂距离鬼两步距离的地方都会被鬼覆盖,且鬼可以穿墙(当然鬼的分身也可分裂); 每秒鬼先分裂,然后M 和 G才走; 问在不遇到鬼的情况下,至少过几秒M和G可以相遇;

0x3f3f3f3f 479

HDU - 3085 Nightmare Ⅱ(双向BFS+曼哈顿距离)

HDU - 3085 Nightmare Ⅱ #include <cstring> #include <iostream> #include <algorithm> #include <queue> using namespace std; typedef pair<int, int> PII; const int N = 810; int n, m; char g[N][N]; int st[N][N]; PII ghost[2];

00后的博客 421

hdu3085 Nightmare双向BFS 模板题

Nightmare ⅡTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3068    Accepted Submission(s): 874Problem DescriptionLast night, little erriyue had ...

popcjz的博客 2124

HDU 3085 Nightmare Ⅱ [双向BFS]

Nightmare Ⅱ Problem Description Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were trapped in a big maze separately. More terribly, there are two ghosts...

Janice_zh的博客 376

hdu 3085 Nightmare Ⅱ (双向bfs

Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 716    Accepted Submission(s): 133 Problem Description Last night, litt

To be what you what to be! 1605

HDU3085 Nightmare Ⅱ —— 双向BFS + 曼哈顿距离

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2790    Accepted Sub

A man can be destroyed, but not defeated. 1203

hdu3085Nightmare Ⅱ(双向BFS)

Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4397 Accepted Submission(s): 1269 Problem Description Last night, little erriyue...

IDrandom的专栏 370

HDU - 3085 Nightmare双向bfs

Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were trapped in a big maze separately. More terribly, there are two ghosts in the maze. They will kill the p...

zamaochick的博客 206

HDU - 3085 Nightmare Ⅱ(双向bfs)

题目链接:点击查看 题目大意:给出一个迷宫,一个男孩和一个女孩还有两只鬼,男孩每秒钟走3格,女孩每秒钟走1格,鬼每秒钟向四周分裂2格,问男孩和女孩能否在鬼占领迷宫之前汇合,能的话输出汇合时间,否则输出-1 题目分析:双向bfs模板题,不过在我看来双向bfs和单向bfs没什么区别,就是格式上有点不一样,对于这个题目每次男孩bfs一次,然后女孩bfs一次,注意实时判断当前格子是否已经被鬼占领,每次...

Falcon的博客 537
上一篇: HDU1180 诡异的楼梯[bfs]
下一篇: POJ2488 A Knight's Journey[dfs]
ControlBear
博客等级 码龄11年 34粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值