题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1026
题意:一个n*m的迷宫,每个格子中有一个字符,意义如下:
‘X':不可走。
‘.':可走。
’n‘:走到次格内要花费n秒才能通过。
问从(0,0)到(n-1,m-1)最少要多少秒。
分析:优先队列+BFS,递归打印路径。
Source Code:
#include<cstdio> #include<queue> using namespace std; const int INF=0x3f3f3f3f; const int maxn=105; char map[maxn][maxn]; int stepsum[maxn][maxn]; struct Node1{ int x,y; }pre[maxn][maxn]; struct Node2{ int x,y,sum; bool operator <(const Node2 &a)const{ return sum>a.sum; } }temp,cur; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; int n,m; void Init(){ int i,j; for(i=0;i<n;i++) scanf("%s",map[i]); for(i=0;i<n;i++) for(j=0;j<m;j++) stepsum[i][j]=INF; } bool OK(int x,int y){ if(x>=0&&x<n&&y>=0&&y<m&&map[x][y]!='X') return true; return false; } bool bfs(){ priority_queue<Node2>Q; temp.x=temp.y=temp.sum=0; Q.push(temp); stepsum[0][0]=0; while(!Q.empty()){ cur=Q.top(); Q.pop(); if(cur.x==n-1&&cur.y==m-1) return true; for(int i=0;i<4;i++){ int tx=cur.x+dir[i][0]; int ty=cur.y+dir[i][1]; if(OK(tx,ty)){ temp.x=tx; temp.y=ty; temp.sum=cur.sum+1; if(map[tx][ty]!='.') temp.sum+=map[tx][ty]-'0'; if(stepsum[tx][ty]>temp.sum){ stepsum[tx][ty]=temp.sum; pre[tx][ty].x=cur.x; pre[tx][ty].y=cur.y; Q.push(temp); } } } } return false; } void PrintPath(int x,int y){ if(x==0&&y==0) return ; PrintPath(pre[x][y].x,pre[x][y].y); printf("%ds:(%d,%d)->(%d,%d)\n",stepsum[pre[x][y].x][pre[x][y].y]+1,pre[x][y].x,pre[x][y].y,x,y); if(map[x][y]!='.'){ for(int i=1;i<=map[x][y]-'0';i++) printf("%ds:FIGHT AT (%d,%d)\n",stepsum[pre[x][y].x][pre[x][y].y]+i+1,x,y); } } int main() { while(scanf("%d %d",&n,&m)==2){ Init(); if(bfs()){ printf("It takes %d seconds to reach the target position, let me show you the way.\n",stepsum[n-1][m-1]); PrintPath(n-1,m-1); } else printf("God please help our poor hero.\n"); printf("FINISH\n"); } return 0; }