题目大意:
一个块只能撞到障碍停止,求起点到终点的最少步数
大致思路:
DFS的基础上,由于求最少步数,且被撞的障碍会消失,所以要在dfs后恢复原状
c++:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int Max_n=1000;
int map[25][25];
int cnt,w,h,sx,sy,ans;
int dx[4]={-1,1,0,0}; //方向向量
int dy[4]={0,0,1,-1};
void dfs(int x,int y){
if(cnt>=10) //如果cnt已经大于等于10时就退出
return ;
for(int i=0;i<4;i++){
int x0=x+dx[i],y0=y+dy[i];
if(x0<0||x0>=h||y0<0||y0>=w||map[x0][y0]==1)
continue; //首先判断四周的障碍以及是否出格
for(;x0>=0&&x0<h&&y0>=0&&y0<w;x0+=dx[i],y0+=dy[i]){
if(map[x0][y0]==0) //为0则继续走
continue;
if(map[x0][y0]==3){ //为3则到达终点
cnt++;
ans=min(cnt,ans);
cnt--;
return ;
}
if(map[x0][y0]==1){
map[x0][y0]=0; //为1时进行撞障碍操作
cnt++;
dfs(x0-dx[i],y0-dy[i]);
map[x0][y0]=1;
cnt--;
break;
}
}
}
}
int main(){
while(scanf("%d%d",&w,&h)!=EOF){
if(w==0&&h==0)
break;
memset(map,0,sizeof(map));
for(int i=0;i<h;i++)
for(int j=0;j<w;j++){
scanf("%d",&map[i][j]);
if(map[i][j]==2)
map[i][j]=0,sx=i,sy=j;
}
cnt=0;
ans=Max_n;
dfs(sx,sy);
if(ans==Max_n)
printf("-1\n");
else
printf("%d\n",ans);
}
return 0;
}