题目:POJ3009 Curling 2.0

思路: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; 用来判断测试数据输入完毕