HDU - 3085 Nightmare Ⅱ(双向bfs)

题目链接:点击查看

题目大意:给出一个迷宫,一个男孩和一个女孩还有两只鬼,男孩每秒钟走3格,女孩每秒钟走1格,鬼每秒钟向四周分裂2格,问男孩和女孩能否在鬼占领迷宫之前汇合,能的话输出汇合时间,否则输出-1

题目分析:双向bfs模板题,不过在我看来双向bfs和单向bfs没什么区别,就是格式上有点不一样,对于这个题目每次男孩bfs一次,然后女孩bfs一次,注意实时判断当前格子是否已经被鬼占领,每次向外扩展的时候也不需要用vis数组标记重复了,只需要在原迷宫的基础上打上自己的特殊符号即可,只要另一方遍历到该符号即代表两人相遇,就可以及时返回了

这个题目有一个需要注意的地方,一开始没仔细看题目,想当然的以为M代表的是女生,G代表的是男生,结果正好相反了,当时调了有点时间,回去仔细读了一遍题才发现的。。

代码:

#include
#include 
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef long long LL;

const int inf=0x3f3f3f3f;

const int N=810;

const int b[4][2]={0,1,0,-1,1,0,-1,0};

int n,m,k,step,ans;

char maze[N][N];

struct Node
{
	int x,y;
	Node(int X,int Y)
	{
		x=X;
		y=Y;
	}
	Node(){}
}ghost[2];

queuegg,mm;

bool check(int x,int y)
{
	if(x<0||y<0||x>=n||y>=m)
		return false;
	if(maze[x][y]=='X')
		return false;
	for(int i=0;i<2;i++)
		if(step*2>=abs(x-ghost[i].x)+abs(y-ghost[i].y))
			return false;
	return true;
}

bool bfsgg()
{
	for(int tt=1;tt<=3;tt++)
	{
		queueq(gg);
		while(!q.empty())
		{
			Node cur=q.front();
			q.pop();
			gg.pop();
			if(!check(cur.x,cur.y))
				continue;
			for(int i=0;i<4;i++)
			{
				int xx=cur.x+b[i][0];
				int yy=cur.y+b[i][1];
				if(!check(xx,yy))
					continue;
				if(maze[xx][yy]=='M')
					continue;
				if(maze[xx][yy]=='G')
					return true;
				maze[xx][yy]='M';
				gg.push(Node(xx,yy));
			}
		}
	}
	return false;
}

bool bfsmm()
{
	queueq(mm);
	while(!q.empty())
	{
		Node cur=q.front();
		q.pop();
		mm.pop();
		if(!check(cur.x,cur.y))
			continue;
		for(int i=0;i<4;i++)
		{
			int xx=cur.x+b[i][0];
			int yy=cur.y+b[i][1];
			if(!check(xx,yy))
				continue;
			if(maze[xx][yy]=='G')
				continue;
			if(maze[xx][yy]=='M')
				return true;
			maze[xx][yy]='G';
			mm.push(Node(xx,yy));
		}
	}
	return false;
}

bool solve()
{
	while(!gg.empty())
		gg.pop();
	while(!mm.empty())
		mm.pop();
	step=k=0;
	for(int i=0;i>w;
	while(w--)
	{
		
		scanf("%d%d",&n,&m);
		for(int i=0;i

 

你可能感兴趣的:(bfs)