#include <stdio.h>
#include <stdlib.h>
struct point
{
int x;//行坐标
int y;//列坐标
int hp;//
int step;//从出发点到达该点的步数
}queue[82];
int map[9][12];//map地图
int n,m,min_step,sign=0;//地图有n行m列
int location[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//4个方位
int recnt_step[9][9],recnt_hp[9][9];
//recnt_hp用于记录最近经过该格时小H的最优血量
//recnt_step用于记录最近经过该格时小H的最优步数
int check(int x,int y)//检查
{
if(x>=0&&x<n&&y>=0&&y<m&&map[x][y])//坐标合法且该格不为障碍
{
return 1;
}
return 0;
}
int BFS(int home_x,int home_y)
{
int i,x,y;
int head=0,tail=0;//定义队首、队尾
//从队尾入队
queue[tail].x=home_x;
queue[tail].y=home_y;
queue[tail].hp=6;//刚开始血量为6
tail++;
while(head<tail&&!sign)//在队列未空时
{
if(queue[head].hp>1)//当血量大于1
{
for(i=0;i<4&&!sign;i++)//尝试遍历四个方向
{
//计算坐标
x=queue[head].x+location[i][0];
y=queue[head].y+location[i][1];
if(!check(x,y))//若坐标不合格
{
continue;//直接遍历下一个方向
}
if(recnt_hp[x][y]>=queue[head].hp-1&&recnt_step[x][y]<=queue[head].step+1)//若小H走到该格时,血量不高于前一次并且步数不低于前一次,则说明小H此时的路线一定不是最优解
{
continue;
}
else
{
//新点从队尾入队
queue[tail].x=x;
queue[tail].y=y;
//更新各项指标
queue[tail].step=queue[head].step+1;//从队长到达相邻的格子需要多走1步
queue[tail].hp=map[x][y]==4? 6:queue[head].hp-1;//从队长到达相邻的格子需要多消耗1点血
recnt_hp[x][y]=queue[tail].hp;//更新最优血量
recnt_step[x][y]=queue[tail].step;
if(map[x][y]==3)//若找到家
{
sign=1;
min_step=queue[tail].step;//记录最小步数
}
tail++;
}
}
}
head++;//将队员全部入队的旧队长出队
}
return 0;
}
int main()
{
int i,j;
int home_x,home_y;
//输入数据并搜索出发位置
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
scanf("%d",&map[i][j]);
if(map[i][j]==2)//找到出发位置
{
home_x=i;
home_y=j;
}
}
}
//广搜
BFS(home_x,home_y);
//输出结果
if(sign)//若找到家
{
printf("%d",min_step);
}
else
{
printf("-1");
}
return 0;
}
/**************************************************************
Problem: 1914
User: admin
Language: C
Result: Accepted
Time:28 ms
Memory:1148 kb
****************************************************************/