这道题搞了很久啊。搜索非常好的一道题。昨天想了2小时,以为是深搜,但后来发现深搜怎么也没法输出正确路径。今天拿宽搜试了一下,问题就是普通的队列宽搜没法得到当前时间最小值。看了一下讨论区,发现优先级队列。好久不用了,都忘记了。各种忘记,优先级队列排序都忘掉了。搞了好半天。最后还需要注意的是格式化输出,采用栈格式输出。需要保存每个节点的移动方向。并且注意若终点是怪兽,还是需要"Fight"。这道题目感觉不是一道水题,还挺不错。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <queue> 5 #include <stack> 6 using namespace std; 7 8 #define MAXNUM 105 9 #define isDigit(ch) ch>='0' && ch<='9' 10 11 typedef struct node_st{ 12 int x, y, time; 13 node_st() { 14 15 } 16 node_st(int a, int b, int t) { 17 x = a; y = b; time = t; 18 } 19 friend bool operator < (node_st p, node_st q) { 20 return p.time > q.time; 21 } 22 } node_st; 23 24 priority_queue<node_st> que; 25 26 typedef struct subnode { 27 int x, y; 28 subnode() { 29 30 } 31 subnode (int a, int b) { 32 x = a; y = b; 33 } 34 } subnode; 35 36 stack<subnode> path; 37 char map[MAXNUM][MAXNUM]; 38 bool visit[MAXNUM][MAXNUM]; 39 int pos[MAXNUM][MAXNUM]; 40 int direct[4][2]={{0,-1}, {-1,0}, {0,1}, {1,0}}; 41 int n, m; 42 43 void output(); 44 45 bool check(int x, int y) { 46 if (x>=0 && x<n && y>=0 && y<m) { 47 if (visit[x][y]==false && map[x][y]!='X') 48 return true; 49 else 50 return false; 51 } else 52 return false; 53 } 54 55 void bfs() { 56 node_st cur, next; 57 int newx, newy, newt; 58 59 que.push(node_st(0,0,0)); 60 visit[0][0] = true; 61 while ( !que.empty() ) { 62 cur = que.top(); 63 que.pop(); 64 // printf("cur node: x=%d,y=%d,cur.time=%d ",cur.x, cur.y, cur.time); 65 if (cur.x==n-1 && cur.y==m-1) { 66 printf("It takes %d seconds to reach the target position, let me show you the way. ", cur.time); 67 output(); 68 printf("FINISH "); 69 return ; 70 } 71 for (int i=0; i<4; ++i) { 72 newx = cur.x + direct[i][0]; 73 newy = cur.y + direct[i][1]; 74 newt = cur.time + 1; 75 if ( check(newx, newy) ) { 76 next = node_st(newx, newy, newt); 77 if ( isDigit(map[newx][newy]) ) 78 next.time += map[newx][newy] - '0'; 79 // printf("after check, ch=%c, time=%d ", map[newx][newy], next.time); 80 pos[newx][newy] = i; 81 visit[newx][newy] = true; 82 que.push(next); 83 } 84 } 85 } 86 printf("God please help our poor hero. "); 87 printf("FINISH "); 88 } 89 90 int main() { 91 int i; 92 93 while (scanf("%d %d", &n, &m) != EOF) { 94 getchar(); 95 for (i=0; i<n; ++i) { 96 gets(map[i]); 97 } 98 memset(visit, false, sizeof(visit)); 99 memset(pos, 0, sizeof(pos)); 100 while (!que.empty()) 101 que.pop(); 102 while (!path.empty()) 103 path.pop(); 104 bfs(); 105 } 106 107 return 0; 108 } 109 110 void output() { 111 subnode cur, next; 112 int x, y, i, time = 0; 113 114 x = n-1; y =m-1; 115 while (x||y) { 116 path.push(subnode(x, y)); 117 i = pos[x][y]; 118 x -= direct[i][0]; 119 y -= direct[i][1]; 120 } 121 // Don;t forget to push (0, 0) 122 path.push(subnode(0, 0)); 123 124 cur = path.top(); 125 path.pop(); 126 127 while (!path.empty()) { 128 next = path.top(); 129 130 x = cur.x; 131 y = cur.y; 132 if (map[x][y] != '.') { 133 i = map[x][y] - '0'; 134 while (i--) { 135 printf("%ds:FIGHT AT (%d,%d) ", ++time, x, y); 136 } 137 } 138 time++; 139 printf("%ds:(%d,%d)->(%d,%d) ", time, cur.x, cur.y, next.x, next.y); 140 141 cur = path.top(); 142 path.pop(); 143 } 144 // if final-point has a monster, then ight 145 x = next.x; 146 y = next.y; 147 if (map[x][y] != '.') { 148 i = map[x][y] - '0'; 149 while (i--) { 150 printf("%ds:FIGHT AT (%d,%d) ", ++time, x, y); 151 } 152 } 153 }