题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072
题目大意:伊格内修斯身上的炸弹还有6分钟就要爆炸,他要想办法用最短的时间走出迷宫,0代表一堵墙,表示不可走,1代表没有任何东西,表示可走,2表示起点位置,3表示终点位置,4表示炸弹重置装置。这道题由于有了炸弹重置装置,所以存在着本来无法到达终点,但可以通过迂回策略先前往炸弹重置装置,再前往终点这种可能性。这道题除了可以用dfs写出来,还可以用bfs写出来,不过这里只贴出dfs的代码,bfs的代码下次有时间再贴吧。
代码:
#include<bits/stdc++.h> using namespace std; const int maxn=10; int n,m,vis[maxn][maxn],mp[maxn][maxn],mi,step,Time[maxn][maxn],Len[maxn][maxn]; bool check(int x,int y){//检查是否越界 if(x>=0&&x<n&&y>=0&&y<m) return true; return false; } void dfs(int x,int y,int step,int t){ if(mp[x][y]==3&&t>0){ if(step<mi){ mi=step; } return; } if(mp[x][y]==4) t=6; if(step>=Len[x][y]&&Time[x][y]>=t)//剪枝,如果此时不是最优解则返回; return; Time[x][y]=t; Len[x][y]=step; int next[4][2]={0,1,1,0,0,-1,-1,0}; for(int i=0;i<4;i++){//由于存在时间限制,所以允许不对走过的点进行标记 int nx,ny; nx=x+next[i][0]; ny=y+next[i][1]; if(check(nx,ny)&&mp[nx][ny]!=0&&t>1){ dfs(nx,ny,step+1,t-1); } } } int main(){ int i,j,k,t,sx,sy; cin>>t; while(t--){ cin>>n>>m; memset(vis,0,sizeof(vis)); mi=0x3f3f3f3f;step=0; memset(Time,-1,sizeof(Time)); memset(Len,0x3f3f3f,sizeof(Len)); for(i=0;i<n;i++){ for(j=0;j<m;j++){ cin>>mp[i][j]; if(mp[i][j]==2){ sx=i;sy=j; } } } dfs(sx,sy,0,6); if(mi==0x3f3f3f3f) cout<<-1<<endl; else cout<<mi<<endl; } }