#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 ****************************************************************/