Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 98304/32768 K (Java/Others)
Total Submission(s): 704 Accepted Submission(s): 160
比较恶心的一道BFS题目,题中所设定的规则无法进行很好的抽象,网上参考了他人的思路后才发现大家的写法都算是比较蛮力的。因为这题的题目要求是小人能否走出迷宫,在迷宫中,小主人公能够拿炸弹去炸墙是令人极其蛋疼的,无论如何,这将使得这一炸极富艺术感,可能炸对,亦可能炸错,(程序无法事先知道是是否该炸)而错误的投掷炸弹又会损耗弹药,因此,原图的保留至关重要,不能因为炸弹把墙炸了就在原图上动刀子。原因是你可能炸错了墙。所以这里在每一步中的节点中保留整个图各点的炸药数,复杂的规则致使这一处理变得必需。像一般的BFS一样,同样有如队要求,不过这题比较隐晦,入队的要求是该次身上所有炸弹比上次在该点的炸弹数多。然后就是判定上的一点小技巧,如果某点是墙的话,直接将其炸药数统计好,判定一个点是否可走就只要看该条路径中是否走过改点,后面才判定是否为墙,这样就可以在满足不拆墙的情况下,通过该地方。
代码如下:
1 #include <cstring>
2 #include <cstdlib>
3 #include <cstdio>
4 #include <queue>
5 #include <cctype>
6 #define INF 100000
7 using namespace std;
8
9 int N, M, ans, sx, sy;
10
11 char map[10][10];
12
13 int dir[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
14
15 struct Node
16 {
17 int x, y, vs, step;
18 int mvs[8][8];
19 bool logic( int tx, int ty )
20 {
21 if( tx >= 0 && tx < N && ty >= 0 && ty < M )
22 return true;
23 return false;
24 }
25 bool operator < ( Node t ) const
26 {
27 return step < t.step;
28 }
29 } info;
30
31
32 bool BFS( )
33 {
34 info.x = sx, info.y = sy;
35 info.step= 0, info.vs = 0;
36 memset( info.mvs, -1, sizeof( info.mvs ) ); // 初始化为-1
37 info.mvs[sx][sy] = 0;
38 queue<Node>q;
39 q.push( info );
40 while( !q.empty() )
41 {
42 Node pos = q.front();
43 q.pop();
44 if( ans != INF && pos.step >= ans )
45 continue;
46 for( int i = 0; i < 4; ++i )
47 {
48 int tx = pos.x + dir[i][0], ty = pos.y + dir[i][1];
49 int tt = pos.step, tvs = -1;
50 if( info.logic( tx, ty ) )
51 {
52 if( map[tx][ty] == 'D' )
53 {
54 ans = ans < tt + 1 ? ans : tt + 1;
55 continue;
56 }
57 else if( pos.mvs[tx][ty] > -1 || map[tx][ty] == '.' ) // 该点已经走过
58 tt += 1, tvs = pos.vs;
59 else if( map[tx][ty] == 'X' && pos.vs > 0 )
60 {
61 tt += 2;
62 tvs = pos.vs - 1;
63 }
64 else if( isdigit( map[tx][ty] ) )
65 {
66 tt += 1;
67 tvs = pos.vs + ( map[tx][ty] - '0' );
68 }
69 if( tvs > pos.mvs[tx][ty] )
70 {
71 info.x = tx, info.y = ty, info.step = tt;
72 info.vs = tvs;
73 memcpy( info.mvs, pos.mvs, sizeof( info.mvs ) );
74 info.mvs[tx][ty] = tvs;
75 q.push( info );
76 }
77 }
78 }
79 }
80 if( ans == INF )
81 return false;
82 else
83 return true;
84 }
85
86
87 int main()
88 {
89 while( scanf( "%d %d", &N, &M ), N | M )
90 {
91 for( int i = 0; i < N; ++i )
92 {
93 scanf( "%s", map[i] );
94 for( int j = 0; j < M; ++j )
95 {
96 if( map[i][j] == 'S' )
97 sx = i, sy = j;
98 }
99 }
100 ans = INF;
101 printf( BFS() ? "%d\n" : "-1\n" , ans );
102
103 }
104 return 0;
105 }