ACM H-8 广度优先搜索(BFS)

最近在家上网课的zst由于把switch放在了寝室所以实在无聊透顶,便拉着str一起玩一款名叫《风来的西林》的游戏,在某次刷图的过程中,由于zst炸裂的欧气,一张地图中同时出现了数把螺旋风魔剑,但此剑需要zst和str两人合力才可取得。

由于这款游戏是按时间付费的,所以两人需要尽快取得此剑(即为二人到达剑所在位置的时间之和最少),因此他们找到了机智的你来帮忙解决问题。

Input

多组数据读入到文件结束
每组数据的第一行输入两个整数n, m(2 <= n, m <= 200),即迷宫大小为n*m
接下来n行,每行包括m个字符
'Y'表示zst所在位置
'M'表示str所在位置
'.'表示可以行走的道路
'#'表示不可通过的墙壁
'@'表示螺旋风魔剑所在位置(数量多于一把)
二人每次行动只有上下左右四种方式,每次行动花费11个单位时间

Output

每组样例输出一行一个整数:二人到达同一把剑所在位置的最小时间之和。
保证有解

Sample Input

3 3
Y.@
#..
@.M

Sample Output

44

注意: 有一个测试点是剑周围都是墙体无法拿取。

#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
char map[202][202];//地图 
int n,m;//n*m的数组 
int a[202][202],b[202][202];//分别对应Y,M两个人 
int yidong[4][2]={{1,0},{-1,0},{0,1},{0,-1}};//移动数组,对应上下右左 
struct node{
	int x,y;
};
bool pd(int x,int y,int luxian[202][202])//判断能否移动 
{
	if(x<0||x>=n||y<0||y>=m)//判断边界 
		return false;
	if(luxian[x][y]!=0)//判断是否走过 
		return false;
	if(map[x][y]=='#')//判断是否能通行 
		return false;
	return true;
}
void bfs(int x,int y,int luxian[202][202])//广度优先搜索(BFS) 
{
	queue<node>q;//创建队列 
	node next,last;//创建next为此队列值,last为前一个队列值 
	next.x=x;next.y=y;//对此队列值赋值 
	luxian[x][y]=0;
	q.push(next);//放入队列 
	while(!q.empty())//不为空就继续 
	{
		last=q.front();//计入队列头的值 
		q.pop();//推出 
		for(int i=0;i<4;i++)//上下左右四个方向移动 
		{
			next.x=last.x+yidong[i][0];//x移动值 
			next.y=last.y+yidong[i][1];//y移动值 
			if(pd(next.x,next.y,luxian))//判断是否能走 
			{
				luxian[next.x][next.y]=luxian[last.x][last.y]+1;//沿路做标记 
				q.push(next);//放入队列 
			}
		}
	}
}
int main()
{
	int i,j,ydmin,yx,yy,mx,my;
	while(cin>>n>>m)//此题为多组输入 
	{
		ydmin=1000000;//哨兵 
		memset(a,0,sizeof(a));//来自string头文件 
        memset(b,0,sizeof(b));//因为多组输入所以要对a,b数组清空处理 
        for(i=0;i<n;i++)
        {
        	for(j=0;j<m;j++)
        	{
        		cin>>map[i][j];
        		if(map[i][j]=='Y')//记录Y地址 
        		{
        			yx=i;yy=j;
				}
				else if(map[i][j]=='M')//记录M地址 
				{
					mx=i;my=j;
				}
			}
		}
		bfs(yx,yy,a);//Y开始广搜 
		bfs(mx,my,b);//M开始广搜 
		for(i=0;i<n;i++)
        {
        	for(j=0;j<m;j++)
        	{
        		if(map[i][j]=='@'&&a[i][j]!=0)//有一个测试点是a[i][j]+b[i][j]=0 
        		{
        			ydmin=min(ydmin,a[i][j]+b[i][j]);
				}
			}
		}
		cout<<ydmin*11<<endl;
	}
	return 0;
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 护眼 设计师:闪电赇 返回首页