典型的BFS加状态的问题,题目很好理解,只不过打印路径这里困扰了我许久。不过经过不懈的努力终于AC了。 泪奔。。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026
存在的问题:1、这道BFS可以不需要做标记,而我之前从来没接触过,所以理解起来较慢。2、遇到了打印路径的题就懵了,怎么去打印路径困扰了很久。3、老问题,BFS和DFS的精髓没理解透。
小技巧:1、直接搜索如果Mintime[xx][yy] > Mintime[x][y] + w 的话则替代,而且需要把整个迷宫都搜索一遍。。
2、由于是搜索整个迷宫,所以方向数组的定义可以为: const int move[4][2] = {{1, 0},{-1, 0},{0, -1},{0, 1}};
分别为下、上、左、右。而pre[MAX_LEN][MAX_LEN]数组则保存上一个点的坐标。pre[xx][yy] = i ^ 1;(按位异或相当于取反)。3、deque的应用也是关键,相当于栈!(双向队列)#include<deque>
2 #include <string.h>
3 #include <stdio.h>
4 #include <queue>
5 #include <deque>
6 #define MAX_LEN 101
7 #define INF 0x0fffffff
8 using namespace std;
9
10
11 char maze[MAX_LEN + 10][MAX_LEN + 10];
12 const int move[4][2] = {{1, 0},{-1, 0},{0, -1},{0, 1}};
13 int Mintime[MAX_LEN + 10][MAX_LEN + 10];
14 int pre[MAX_LEN + 10][MAX_LEN + 10]; //保存上一个点的方向值
15 int vis[MAX_LEN + 10][MAX_LEN + 10];
16
17 struct node
18 {
19 int x , y;
20 };
21
22 int N , M;
23
24 bool Check(int x , int y)
25 {
26 if(maze[x][y] != 'X' && x >= 0 && x < N && y >= 0 && y < M)
27 return 1;
28 return 0;
29 }
30
31
32 int getT(char a)
33 {
34 switch(a)
35 {
36 case '.': return 1;
37 case 'X':return INF;
38 default : return a - '0' + 1;
39 }
40 }
41
42
43 void bfs(int N , int M)
44 {
45 queue<node> Q;
46 node in , out;
47 Mintime[0][0] = 0;//初始点时间赋值为0,这里没赋初值。调试了我N时间啊~~靠
48 in.x = 0;
49 in.y = 0;
50 //in.time = 0;
51 Q.push(in);
52 while(!Q.empty())
53 {
54 out = Q.front();
55 Q.pop();
56 int x = out.x;
57 int y = out.y;
58 //vis[x][y] = false;
59 for(int i = 0 ; i < 4 ;i++)
60 {
61 int xx = x + move[i][0];
62 int yy = y + move[i][1];
63 if(Check(xx , yy))
64 {
65
66 //in.time = out.time + getT(xx , yy);
67 //vis[xx][yy] = true;
68 int w = getT(maze[x][y]);
69 //if(w == INF) continue;
70 if(Mintime[xx][yy] > Mintime[x][y] + w)
71 {
72 Mintime[xx][yy] = Mintime[x][y] + w;
73 pre[xx][yy] = i ^ 1; //为了求上一步。
74 if(!vis[xx][yy])
75 {
76 in.x = xx;
77 in.y = yy;
78 Q.push(in);
79 //vis[xx][yy] = true;
80 }
81 }
82 }
83 }
84 }
85 }//广搜
86
87
88 void dfs(int N , int M)
89 {
90 deque<node> Q;
91 node in , out;
92 in.x = N-1; in.y = M-1;
93 pre[0][0] = INF;
94 Q.push_back(in);
95 while(true)
96 {
97 out = Q.back();
98 int x = out.x;
99 int y = out.y;
100 if(pre[x][y] == INF) break;
101 int m = pre[x][y];
102 in.x = x + move[m][0];
103 in.y = y + move[m][1];
104 Q.push_back(in);
105 }
106 int time = 1; int w = getT(maze[0][0]);
107 for(int i = 1 ;i < w ; i++)
108 printf("%ds:FIGHT AT (0,0)\n", time++);
109 while(!Q.empty())
110 {
111 in = Q.back();
112 Q.pop_back();
113 int x = in.x;
114 int y = in.y;
115 int t = getT(maze[x][y]);
116 for(int i = 1; i < t ;i++)
117 printf("%ds:FIGHT AT (%d,%d)\n",time++ , x , y);
118 if(x == N-1 && y == M-1) break;
119 out = Q.back();
120 printf("%ds:(%d,%d)->(%d,%d)\n", time++ , x , y , out.x , out.y);
121 }
122 }
123
124
125 int main()
126 {
127 while(~scanf("%d%d", &N , &M))
128 {
129 for(int i = 0 ;i < N ; i++)
130 {
131 scanf("%s", maze[i]);
132 }
133 for(int i = 0 ;i < N; i++)
134 {
135 for(int j = 0 ;j < M; j++)
136 {
137 Mintime[i][j] = INF;
138 }
139 }
140 //memset(Mintime , INF , sizeof(Mintime));
141 memset(vis , 0 , sizeof(vis));
142 memset(pre , 0 ,sizeof(pre));
143
144 bfs(N , M);
145
146 if(Mintime[N-1][M-1] == INF)
147 printf("God please help our poor hero.\n");
148 else
149 {
150 int w = getT(maze[N-1][M-1]); //出口处是否有怪兽,有的话时间也要增加
151 printf("It takes %d seconds to reach the target position,",Mintime[N-1][M-1] + w -1);
152 printf(" let me show you the way.\n");
153 dfs(N , M);
154 }
155 printf("FINISH\n");
156 }
157 return 0;
158 }