小白回家
描述
小白在一个封闭的空地上,该空地被分割成了n*m个方格。每次他能向上下左右四个方向移动一格(不可以静止不动~),小白一旦离开封锁线就会被打死。一开始他满血为6点,每移动一格他要消耗1点血量。一旦小白的血量降到0,他将死去。他可以沿路通过拾取bug来补满血量。只要他走到有bug的方格,他不需要任何时间即可拾取。格子上的bug可以瞬间补满,所以每次经过这个格子都有bug。就算到了某个有bug的格子才死去, 他也不能通过拾取bug补满HP。即使在家门口死去,他也不能算完成任务回到家中。地图上有 5 种格子:
数字0: 障碍物。
数字1: 空地,小白可以自由行走。
数字2: 小白出发点,也是一片空地。
数字3: 小白的家。
数字4: 有bug在上面的空地。
小白能否安全回家?如果能,最短需要多长时间呢?
输入
第一行两个整数n,m,表示地图的大小为n*m。
下面n行,每行m个数字来描述地图。
输出
一行,若小白不能回家,输出-1,否则输出他回家所需最短时间。
输入样例 1
3 3
2 1 1
1 1 0
1 1 3
输出样例 1
4
代码:
/*
一个dfs水题,只要注意判断各种情况就行了
要注意数组不要开的太大,容易RE
*/
#include<cstdio>
using namespace std;
#define MAXN 0xffffff
int a[101][101],n,m,x0,x2,tot;
int y0,y2,maxx=MAXN,b[101][101];
int xx[4]={-1,0,1,0},yy[4]={0,1,0,-1};
int min(int x,int y)
{
if(x<y)
return x;
return y;
}
void dfs(int x,int y,int z)
{
b[x][y]=1;
if(x==x2&&y==y2)//判断是否到达终点
{
maxx=min(maxx,tot);
return ;
}
if(a[x][y]==4)
z=6;
for(int i=0;i<4;i++)
{
int x1=x+xx[i],y1=y+yy[i];
if(x1<=0||x1>n||y1<=0||y1>m)//判断边界条件
continue;
if(b[x1][y1]==0&&a[x1][y1]&&z>0)
{
tot++;
dfs(x+xx[i],y+yy[i],z--);
b[x+xx[i]][y+yy[i]]=0;//回溯
z++;
tot--;
b[x1][y1]=0;
}
}
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
if(a[i][j]==2)
{
x0=i;
y0=j;
}
if(a[i][j]==3)
{
x2=i;
y2=j;
}
}
dfs(x0,y0,6);
if(maxx!=MAXN)
printf("%d",maxx);
else
printf("-1");
return 0;
}```