http://poj.org/problem?id=3009
题意 : 迷宫升级版,也是m*n的迷宫,0是可以走的,1是阻塞,2是初始点,3是目标位置,这个的阻塞是可以消除的,就是说只要石头撞到阻塞,阻塞就由1变为0了,石头这个时候是可以停下来的,也就是说石头只有撞上阻塞停下来才算走了一步,还有要注意的一点是石头停了下来的时候不是停在阻塞那个点那的,还是它撞阻塞之前的那个位置,求出走到目标位置需要的步数,若步数超过了10步就输出-1;
思路 : 典型的DFS,递归就行,不过注意一下结束条件就行了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> #include<iostream> using namespace std ; const int maxn = 1010 ; int ch[maxn][maxn] ; int ans,m,n; int dix[] = {0,0,-1,1} ;//x轴方向上的变化,分别为上下左右 int diy[] = {1,-1,0,0} ; void dfs(int i,int j,int step)//i,j为初始的坐标,step为走的步数 { if(step >= 10||step>=ans)//如果步数超出10或者步数大于最小移动次数 return ; int x,y; for(int h = 0 ; h < 4 ; h++)//四个方向进行遍历 { x = i+dix[h] ; y = j+diy[h] ; if(ch[x][y] == 1)//如果是阻塞,就跳出 continue ; while(1) { if(x>=0&&x<n&&y >= 0&&y < m)//没有超出边界 { if(ch[x][y] == 1) { ch[x][y] = 0 ;//因为撞到阻塞就可以让阻塞消除,并且可以停止 dfs(x-dix[h],y-diy[h],step+1);//然后再4个方向进行遍历 ch[x][y] = 1 ;//若是没找到就再恢复原样 break ; } if(ch[x][y] == 3) { ans = min(ans,step+1); break; } } else if(!(x>=0&&x<n&&y >= 0&&y < m)) break; x += dix[h];//如果未遇到阻塞就一直往前走 y += diy[h]; } } } int main() { while(cin>>m>>n) { if(n == 0&&m == 0) break ; int x,y ; ans = 11;//ans为从开始位置到目标位置的最少移动次数,初始化为11 for(int i = 0 ; i < n ; i++) { for(int j = 0 ; j < m ; j++) { cin>>ch[i][j] ; if(ch[i][j] == 2)//记录下初始位置的横纵坐标 { x = i ; y = j ; } } } dfs(x,y,0) ; if(ans==11) printf("-1 "); else printf("%d ",ans); } return 0; }