这个题目一开始没想到用优先队列,或许说没学过优先队列,结果卡死了。然后看了别人的题解,原来如此,基本方法就是BFS。
优先队列的基本用法:http://blog.youkuaiyun.com/baochunzhi/article/details/7664422,讲解还是比较详细。
这题还有一个注意点就是如何输出,这里就要注意前后的关系,我是用next数组来表示前后两点的相对关系,具体可以见代码。输出的时候用到递归,从后往前输。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
struct node
{
int x,y;
int time;
friend bool operator<(node n1,node n2)
{
return n2.time<n1.time;
}
};
const int N=105;
int map[N][N],next[N][N],n,m,t;
bool visited[N][N];//标志是否访问过
int dx[]={1,0,-1,0};
int dy[]={0,1,0,-1};
bool judge(int x,int y)
{
return (x>=0&&x<n)&&(y>=0&&y<m);
}
int bfs()
{
memset(visited,false,sizeof(visited));
priority_queue<node> que;
node cur,_next;
cur.x=0,cur.y=0,cur.time=0;
que.push(cur);
visited[0][0]=true;
while(!que.empty())
{
cur=que.top();
que.pop();
if(cur.x==n-1&&cur.y==m-1)
return cur.time;
for(int i=0;i<4;i++)
{
int x=cur.x+dx[i];
int y=cur.y+dy[i];
if(judge(x,y)&&visited[x][y]==false&&map[x][y]!=-1)
{
_next.x=x,_next.y=y;
_next.time=cur.time+1+map[x][y];//这里要注意加上1,除了打怪兽消耗的时间,还有加上移动的1秒。
next[x][y]=i+1;//这里就表示了两者之间的相对关系,也就是x,y的关系。
visited[x][y]=true;
que.push(_next);
}
}
}
return -1;
}
void print(int x,int y)
{
if(next[x][y]==0)
return;
int pre_x=x-dx[next[x][y]-1];//这里就展现了如何寻找前面一点。
int pre_y=y-dy[next[x][y]-1];
print(pre_x,pre_y);
printf("%ds:(%d,%d)->(%d,%d)\n",t++,pre_x,pre_y,x,y);
while(map[x][y]--)
printf("%ds:FIGHT AT (%d,%d)\n",t++,x,y);
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
memset(next,0,sizeof(next));
char s[N];
for(int i=0;i<n;i++)
{
scanf("%s",s);
for(int j=0;j<m;j++)
{
if(s[j]=='.')
map[i][j]=0;
else if(s[j]=='X')
map[i][j]=-1;
else
map[i][j]=s[j]-'0';
}
}
int ans=bfs();
if(ans==-1)
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",ans);
t=1;
print(n-1,m-1);
}
printf("FINISH\n");
}
return 0;
}