鉴于没多少人看过这道题,给传送门:2428: How to be An ACMan,这道题类似于hdu1242这道题,但是比其难一些,因为分小坑和大坑,所以要多考虑一种,但是也是很简单的,1242题解传送门:Hdu1242 - Rescue - 广度优先搜索
#include<stdio.h>
#include<string.h>
int m,n;
char map[210][210];
int mark[210][210][3];
int to[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
struct point
{
int x,y,step;
int bury;//0没有坑
}queue[1000010],st,ed,now;
void bfs()
{
memset(mark,0,sizeof(mark));
int head,tail,i;
int nx,ny;
head=tail=0;
st.step=0;
st.bury=0;
queue[tail++]=st;
mark[st.x][st.y][st.bury]=1;
while(head<tail)
{
now=queue[head++];//取出队列中当前首项
if(now.bury!=0)//如果有坑
{
point item=now;
item.bury--;//坑填掉
if(mark[item.x][item.y][item.bury]==0)//如果该点没被标记过
{
mark[item.x][item.y][item.bury]=1;//标记
item.step++;//步数加一
queue[tail++]=item;//加入队列
}
continue;
}
for(i=0;i<4;i++)//如果没坑
{
nx=now.x+to[i][0];
ny=now.y+to[i][1];
point item=now;
if(nx<0||ny<0||nx>=m||ny>=n||map[nx][ny]=='#')//如果下一步超出边界或者是墙
{
continue;//跳过加入队列
}
if(nx==ed.x&&ny==ed.y)//如果结束
{
printf("%d\n",now.step+1);//输出结果步数
return ;//结束
}
int burys=0;//设置一个变量没坑
if(map[nx][ny]=='x')//如果下一个位置有坑
{
burys=1;//变量为小坑
}
if(map[nx][ny]=='X')//如果下一个位置有坑
{
burys=2;//变量为大坑
}
if(mark[nx][ny][burys]==1)//如果下一个位置被标记过
{
continue;//跳过加入队列
}
mark[nx][ny][burys]=1;//标记下一位置
item.bury=burys;//进入下一位置
item.x=nx;//进入下一位置
item.y=ny;//进入下一位置
item.step++;//步数加一
queue[tail++]=item;//加入队列尾
}
}
puts("-1");
return ;
}
int main()
{
int t;
while(scanf("%d",&t)!=EOF)
{
while(t--)
{
scanf("%d%d",&m,&n);
for(int i=0;i<m;i++)
{
scanf("%s",map[i]);
}
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(map[i][j]=='g')
{
st.x=i;
st.y=j;
}
else if(map[i][j]=='p')
{
ed.x=i;
ed.y=j;
}
}
}
bfs();
}
}
}