做了4个小时,不容易啊,特别是路径保存,特别郁闷 ,最后终于想到了方法,
题意:就是从一点(0,0)——》(n,m),中途会遇见很多的情况:'x'----->陷阱,'.'------>load,'',数字1~9表示怪兽的血量,也就是你要停留几秒,很简单的bfs()+priority_queue,但是,路径保存,不好想,你需要记录当前最犹节点的前驱节点;然后反向bfs()#include<stdio.h>
#include<string.h>
#include<queue>
#include<malloc.h>
#include<iostream>
using namespace std;
char map[136][136]; //地图
int vis[141][141]; //标记
int n,m;
typedef struct Node
{
int x,y,step;
}aa;
struct cmp
{
bool operator()(aa a,aa b)
{
return a.step>b.step;
}
};
struct N
{
int x,y;
}pre[101][101];
priority_queue <aa,vector<aa>,cmp> Q;// 优先队列
int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};
int bfs()
{
while(!Q.empty())
{
aa Ac=Q.top();
aa bb;
Q.pop();
for(int i=0;i<4;i++)
{
int x = Ac.x + dx[i];
int y = Ac.y + dy[i];
if(x==1&&y==1)
{
pre[x][y].x = Ac.x; //记录路径
pre[x][y].y = Ac.y;
return Ac.step + map[x][y];
}
if(map[x][y]!=-1&&!vis[x][y])
{
/* 此为精华*/
pre[x][y].x = Ac.x;
pre[x][y].y = Ac.y;
/* 此为精华*/
vis[x][y] = 1;
bb.x = x;
bb.y = y;
bb.step = Ac.step+map[x][y];
Q.push(bb);
}
}
}
return -1;
}
int main()
{
while(cin>>n>>m)
{
while(!Q.empty())Q.pop();
memset(map,-1,sizeof(map));
memset(vis,0,sizeof(vis));
getchar();
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
char c = getchar();
switch(c)
{
case'X':map[i][j] = -1;break;
case '.':map[i][j] = 1;break;
}
if(c>'0'&&c<='9')
map[i][j] = c - '0'+1; // 地图装换
}
getchar();
}
vis[n][m] = 1;
aa bb;
bb.x = n;
bb.y = m;
bb.step = map[n][m]; //反向 bfs();
Q.push(bb);
int num = bfs();
if(num==-1)
puts("God please help our poor hero.") ;
else
{
printf("It takes %d seconds to reach the target position, let me show you the way.\n",num-1);
int x = 1,y = 1;
int cn = 1;
while(1)
{
printf("%ds:",cn++);
int tx = pre[x][y].x; //路径输出
int ty = pre[x][y].y;
printf("(%d,%d)->(%d,%d)\n",x-1,y-1,tx-1,ty-1);
if(map[tx][ty]>1)
for(int i=1;i<map[tx][ty];i++)
printf("%ds:FIGHT AT (%d,%d)\n",cn++,tx-1,ty-1);
if(tx==n&&ty==m)break;
x = tx;
y = ty;
}
}
puts("FINISH");
}
}
;