https://vjudge.net/problem/POJ-3009
做完这道题,感觉自己对dfs的理解应该又深刻了。
1.一般来说最小步数都用bfs求,但是这题因为状态记录很麻烦,所以可以用dfs。
2.在用dfs的时候,mp时一个全局变量,对于平等的走法,每一个走法结束后一定要状态复原!!!(也就是代码36行)否则会对其他走法产生影响。
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<stack> 8 #define lson l, m, rt<<1 9 #define rson m+1, r, rt<<1|1 10 #define IO ios::sync_with_stdio(false);cin.tie(0); 11 #define INF 0x3f3f3f3f 12 typedef unsigned long long ll; 13 using namespace std; 14 int n, m, mp[30][30], si, sj, gi, gj, cnt, mini; 15 int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; 16 void dfs(int x, int y, int a, int b, int k, int c) 17 { 18 if(k > 10||k > mini) return ; 19 if(x == gi&&y == gj){ 20 mini = min(mini, k); 21 return ; 22 } 23 if(a != 0||b != 0){//不是刚开始 24 if(x<0||x>=n||y<0||y>=m){ 25 return;//失败 26 } 27 else if(mp[x][y] == 1){ 28 if(c <= 1) return ; 29 c = 0; 30 mp[x][y] = 0;//该阻被消去 31 x -= a; 32 y -= b;//回到上一状态 33 for(int i = 0; i < 4; i++){ 34 dfs(x+dir[i][0], y+dir[i][1], dir[i][0], dir[i][1], k+1, c+1); 35 } 36 mp[x][y] = 1;//记住要状态复原!!!!! 37 } 38 else{ 39 dfs(x+a, y+b, a, b, k, c+1); 40 } 41 } 42 else{ 43 for(int i = 0; i < 4; i++){ 44 dfs(x+dir[i][0], y+dir[i][1], dir[i][0], dir[i][1], k+1, c+1); 45 } 46 } 47 } 48 int main() 49 { 50 while(cin >> m >> n, n, m){ 51 mini = INF; 52 cnt=0; 53 for(int i = 0; i < n; i++){ 54 for(int j = 0; j < m; j++){ 55 cin >> mp[i][j]; 56 if(mp[i][j] == 2) si=i,sj=j; 57 if(mp[i][j] == 3) gi=i,gj=j; 58 } 59 } 60 dfs(si, sj, 0, 0, 0, 0); 61 if(mini == INF) cout << "-1" << endl; 62 else cout << mini << endl; 63 } 64 return 0; 65 }