///WA两次:第一次未清空队列. 第二次没有考虑到倒数第二步在打怪的情况,缺少少输出。 广搜,输出最佳路径 ///广搜:与以前做的题的情况有点不同,不能根据有没有访问过这一点而决定是否 ///放弃这个点,即使以前已经访问过,但是还是需要将其考虑,因为以前访问得到的时间 ///不能保证是最小的,在第二次访问的时候就需要判断时间,若后一次时间少,更新访问到 ///这一点的最小时间即sc[i][j]中保存的值,并且将这一点再次入栈,若后一次时间多就可以 //放弃这个点了。 ///输出最佳路径: 这里采用的是保存从前一个点到当前点的方向。输出时从最后一个点向 ///前推,直至推到0,0这个点为止。当然以前也写过不用保存方向,而通过从(0,0)开始深搜 ///也能够输出最佳路径。 #include<stdio.h> #include<string.h> #include<queue> using namespace std; queue<int> q; char map[105][105]; int f[105][105],sc[105][105]; int n,m,min,times; int di[4][2]={-1,0,1,0,0,-1,0,1}; int back_path(int a,int b) { if(f[a][b]!=-1) { int c,d; if(f[a][b]%2) c=f[a][b]-1; else c=f[a][b]+1; if(a+di[c][0]==0&&b+di[c][1]==0) { printf("%ds:(%d,%d)->(%d,%d)/n",times++,a+di[c][0],b+di[c][1],a,b); if(map[a][b]>'0'&&map[a][b]<='9') { int t=map[a][b]-'0'; while(t--) { printf("%ds:FIGHT AT (%d,%d)/n",times++,a,b); } } } else { back_path(a+di[c][0],b+di[c][1]); printf("%ds:(%d,%d)->(%d,%d)/n",times++,a+di[c][0],b+di[c][1],a,b); if(map[a][b]>'0'&&map[a][b]<='9') { int t=map[a][b]-'0'; while(t--) { printf("%ds:FIGHT AT (%d,%d)/n",times++,a,b); } } } } return 0; } int bfs(int a,int b) { memset(sc,0,sizeof(sc)); sc[a][b]=0;f[a][b]=-1; q.push(a);q.push(b); while(!q.empty()) { int c,d; c=q.front();q.pop(); d=q.front();q.pop(); int i,j,t,h; for(i=0;i<4;i++) { t=c+di[i][0]; h=d+di[i][1]; //printf("%d~~~~%d/n",t,h); if(t>=0&&t<n&&h>=0&&h<m) { if(sc[t][h]==0&&!(t==0&&h==0)) { if(map[t][h]=='.') { sc[t][h]=sc[c][d]+1; f[t][h]=i; q.push(t);q.push(h); } if(map[t][h]>'0'&&map[t][h]<='9') { sc[t][h]=sc[c][d]+1+map[t][h]-'0'; f[t][h]=i; q.push(t);q.push(h); } } else { if(map[t][h]=='.'&&sc[c][d]+1<sc[t][h]) { sc[t][h]=sc[c][d]+1; f[t][h]=i; q.push(t);q.push(h); } if(map[t][h]>'0'&&map[t][h]<='9'&&sc[c][d]+1+map[t][h]-'0'<sc[t][h]) { sc[t][h]=sc[c][d]+1+map[t][h]-'0'; f[t][h]=i; q.push(t);q.push(h); } } } } } if(sc[n-1][m-1]) { printf("It takes %d seconds to reach the target position, let me show you the way./n",sc[n-1][m-1]); back_path(n-1,m-1); printf("FINISH/n"); } else { printf("God please help our poor hero./n"); printf("FINISH/n"); } return 0; } int main() { while(scanf("%d%d",&n,&m)!=EOF) { int i,j; for(i=0;i<n;i++) scanf("%s",map[i]); times=1; bfs(0,0); while(!q.empty()) q.pop(); } return 0; }