最近在家上网课的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;
}