题意:给你一个迷宫,2代表你当前的位置,0代表墙,1代表可走的路,3代表出口,4代表的是炸弹的重置点,一开始炸弹的倒计时设置为6,每走一步时间减少1,倒计时到0的时候走到3或者4都不可以,问走出迷宫的最小步数,没有则输出-1.
思路:dfs剪枝,这里的剪枝有点不一样,因为这里可以回溯的走,也就是可以走回头路,所以不能以走过的路来标记,这里的标记方法呢,就是以最短路径和当前位置离爆炸时间长度来标记.
#include<iostream> #include<cstdio> #include<cstring> #include<climits> using namespace std; const int qq=10,no=1e7; int map[qq][qq],step[qq][qq],time[qq][qq]; int n,m,tx,ty,minx,p; void dfs(int x,int y,int cnt,int p) { if(x<0||y<0||x>=n||y>=m) return; if(cnt>=minx||p<=0) return; if(map[x][y]==0) return; if(map[x][y]==3) if(cnt<minx) minx=cnt; if(map[x][y]==4) p=6; if(cnt>=step[x][y] && time[x][y]>=p)return; //关键标记、 step[x][y]=cnt; time[x][y]=p; dfs(x,y+1,cnt+1,p-1); dfs(x,y-1,cnt+1,p-1); dfs(x+1,y,cnt+1,p-1); dfs(x-1,y,cnt+1,p-1); return; } int main() { int t; cin >> t; while(t--){ cin >> n >> m; int sx,sy; for(int j,i=0;i<n;++i) for(j=0;j<m;++j){ cin >> map[i][j]; if(map[i][j]==2){ sx=i;sy=j; } if(map[i][j]==3){ tx=i;ty=j; } step[i][j]=INT_MAX; } minx=no; dfs(sx,sy,0,6); if(minx==no) cout << "-1" << endl; else cout << minx << endl; } }