思路:DFS + 回溯
//照着别人的代码写的,测试数据输出正确,但没有AC,没有找到原因
//经@Lorazepam 提示,下面这行代码的h和w写反了...
66 while(scanf("%d %d", &h, &w) != EOF)
//每个地图有n种路线,每条路线都会改变地图,因此每次搜索完毕得到结果(goal)后,要复原地图
//每次递归DFS,就代表碰到了墙,需改变路线,因此要 step + 1
//每条路线所用步数不同,题目求最小步数,因此要 goal = min(goal, step)
1 #include <iostream> 2 #include <stdio.h> 3 4 using namespace std; 5 6 int w; 7 int h; 8 const int INF = 0x3f3f3f3f; //常用的无穷大常量 9 int goal; 10 int res[100]; 11 int sx; 12 int sy; 13 int dx[4] = {-1, 0, 1, 0}; 14 int dy[4] = {0, 1, 0, -1}; 15 16 int board[25][25]; 17 18 bool isNotOut(int x, int y) { 19 if(x < 0 || y < 0 || x >= h || y >= w) { 20 return false; 21 } 22 return true; 23 } 24 25 26 void dfs(int step, int x, int y) { 27 int nx; 28 int ny; 29 30 if(step > 10) { 31 return ; 32 } 33 34 for(int i = 0; i < 4; i++) { 35 nx = x + dx[i]; 36 ny = y + dy[i]; 37 38 if(!isNotOut(nx, ny)) { 39 continue; 40 } 41 if(board[nx][ny] == 1) { 42 continue; 43 } 44 while(!board[nx][ny]) { 45 nx += dx[i]; 46 ny += dy[i]; 47 if(!isNotOut(nx, ny)) { 48 break; 49 } 50 } 51 if(isNotOut(nx, ny)) { 52 if(board[nx][ny] == 3) { 53 goal = min(goal, step); 54 } 55 if(board[nx][ny] == 1) { 56 board[nx][ny] = 0; 57 dfs(step + 1, nx - dx[i], ny - dy[i]); 58 board[nx][ny] = 1; 59 } 60 } 61 } 62 } 63 64 int main() { 65 int n = 0; 66 while(scanf("%d %d", &h, &w) != EOF) { 67 if(w == 0 && h == 0) { 68 break; 69 } 70 for(int i = 0; i < h; i++) { 71 for(int j = 0; j < w; j++) { 72 scanf("%d", &board[i][j]); 73 if(board[i][j] == 2) { 74 sx = i; 75 sy = j; 76 board[i][j] = 0; 77 } 78 } 79 } 80 goal = INF; 81 dfs(1, sx, sy); 82 res[n] = goal; 83 n++; 84 } 85 for (int i = 0; i < n; i++) { 86 if(res[i] != INF) { 87 printf("%d\n", res[i]); 88 } else { 89 printf("-1\n"); 90 } 91 } 92 return 0; 93 }
额外收获:
- while (scanf() != EOF) 或者 while (~scanf()),结合 if(w == 0 && h == 0) break; 用来判断测试数据输入完毕