题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026
典型的广度优先搜索,其实这个我已经写了很多遍了,但是写这个代码的时候还是花了我一上午的时间,为什么呢,以为我写代码的时候把中间最优值更新的部分的map[nx][ny]敲成了map[x][y],血淋淋的教训啊,尼玛,很熟练的写完了,调试了很久都觉得没错了。唉,所以说还有要细心一点啊。这种输入错误,很难找的。唉!不说了,说多了全是泪啊。其实这里可以用循环链表,这样比较节约空间,不过,鉴于现在没时间,先这样了呗~~
代码:
#include <stdio.h> #include<string.h> #define M 105 char map[M][M]; int used[M][M]; int dp[M][M]; int queue[2][5*M*M]; int stack[2][M*M]; int derect[2][4] = {{0,1,0,-1},{1,0,-1,0}};//右,下,左,上 void BFS(int n, int m)//n行m列 { int head,tail; int i,x,y; int nx,ny; queue[0][0] = 0; queue[0][0] = 0; head = 0; tail = 1; dp[0][0] = 0; used[0][0] = 0; while(head < tail) { x = queue[0][head]; y = queue[1][head]; for(i = 0; i < 4; ++i) { nx = x + derect[0][i]; ny = y + derect[1][i]; if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue; if(used[nx][ny] < 0)//如果还没有标记过 { used[nx][ny] = (i + 2)%4;//求反方向 dp[nx][ny] += dp[x][y]; queue[0][tail] = nx; queue[1][tail++] = ny; } else if(map[nx][ny] != 'X')//标记过之后,更新到这一点最短距离 { if(map[nx][ny] == '.' && dp[x][y] + 1 < dp[nx][ny]) { dp[nx][ny] = dp[x][y] + 1; used[nx][ny] = (i + 2) % 4; queue[0][tail] = nx;//最短路得到更新过后的数据要再次进队列,以便更新其后续的点 queue[1][tail++] = ny; } else if( map[nx][ny] != '.' && map[nx][ny] - '0' + dp[x][y] + 1 < dp[nx][ny]) { dp[nx][ny] = map[nx][ny] - '0' + dp[x][y] + 1; used[nx][ny] = (i + 2) % 4; queue[0][tail] = nx;//最短路得到更新过后的数据要再次进队列,以便更新其后续的点 queue[1][tail++] = ny; } } }//for(i = 0; i < 4; ++i) ++head; }//end while(head < tail) } void GetPath(int n, int m) { int x,y; int temp; int top = 0; x = n - 1; y = m - 1; while(x || y) { stack[0][top] = x; stack[1][top] = y; temp = used[x][y]; x += derect[0][temp]; y += derect[1][temp]; ++top; } stack[0][top] = 0; stack[1][top] = 0; top = top - 1; temp = 1; while(top >= 0) { x = stack[0][top]; y = stack[1][top]; printf("%ds:(%d,%d)->(%d,%d)\n",temp++,stack[0][top+1],stack[1][top+1],x,y); for( ; temp <= dp[x][y]; ++temp)//如果在某一点有停留,打印fight { printf("%ds:FIGHT AT (%d,%d)\n",temp,x,y); } --top; } } void main() { int n,m; int i,j; while(scanf("%d %d",&n,&m) != EOF) { getchar(); memset(dp,0,sizeof(dp)); for(i = 0; i < n; ++i) { for(j = 0; j < m; ++j) { used[i][j] = -1; scanf("%c",&map[i][j]); if(map[i][j] == 'X') { used[i][j] = 5; } else if(map[i][j] == '.') { dp[i][j] = 1; } else { dp[i][j] = map[i][j] -'0' + 1; } } getchar(); } BFS(n,m); if(used[n-1][m-1] < 0) { printf("God please help our poor hero.\n"); } else { printf("It takes %d seconds to reach the target position, let me show you the way.\n",dp[n-1][m-1]); GetPath(n,m); } printf("FINISH\n"); } }