题目意思就是说, hero 去城堡里救公主; 城堡的规模是n * m 的, 刚开始的时候hero是在(0,0)位置, 要求hero最终到达(n-1, m-1)的最少时间,并输出路径;
输入包含n行m列字符串
‘ . ’ 表示可以走的地方
‘0’ - ‘9’ 代表怪物的血量, 杀死怪物需要时间, 怪物有多少血量就要多少时间
‘X’ 表示墙, 怪物不可以走
这个题麻烦的是输出路径, 其他的都简单, 也就是一个简单的bfs而已; 这里可以建立一个路径数组来保存路径就可以了;
这里注意 需要反向扫, 也就是说从 (n-1, m-1)的地方开始扫, 这样, 在当前位置保存上一步位置的值, 放最后输出路径
的时候就是正向的了
#include<bits/stdc++.h>
using namespace std;
const int maxn = 120;
int vis[maxn][maxn];
int dir[4][2] = {0,-1,0,1,-1,0,1,0};
int n,m;
struct node{ //结构体,保存位置和时间
int x,y,time;
friend bool operator < (node a, node b) //排序函数直接写在这里面简单一些
{
return a.time > b.time;
}
};
struct path{ //保存图和路径的结构体
int x, y;
char c;
};
path a[maxn][maxn]; //地图 数组
int bfs()
{
node now, next;
priority_queue<node> q; //优先队列,要求最短时间,在这里可以用
while(q.empty() == 0) //如果队列为非空, 就拿出来,直到最烈清空
{
q.pop();
}
now.x = n-1; //从后向前扫是为了,把上一步的路劲保存到当前位置来,这样正向扫一遍就是正向的路径了
now.y = m-1;
if(a[now.x][now.y].c >= '0' && a[now.x][now.y].c <= '9') //如果当前位置有怪物, 就杀掉
{
now.time = a[now.x][now.y].c - '0';
}
else //否则初始时间就为 0
now.time = 0;
q.push(now); //把当前位置压入队列中
while(q.empty() == 0) //如果队列为非空
{
now = q.top(); //找到队列顶部元素
q.pop(); //出队
if(now.x == 0 && now.y ==0) //如果搜到刚开始的地方 bfs结束, 返回时间
return now.time;
for(int i = 0; i < 4; i++) //四个方向 搜索
{
next.x = now.x + dir[i][0];
next.y = now.y + dir[i][1];
if(next.x >= 0 && next.x < n && next.y >= 0 && next.y < m && !vis[next.x][next.y] && a[next.x][next.y].c != 'X')
{
vis[next.x][next.y] = 1; //访问数组
next.time = now.time + 1; //访问时间
if(a[next.x][next.y].c >= '0' && a[next.x][next.y].c <= '9')
{
next.time += a[next.x][next.y].c - '0'; //如果有怪物, 要加上杀怪物的时间
}
a[next.x][next.y].x = now.x; //保存上一步的路径
a[next.x][next.y].y = now.y; //保存上一步的路径
q.push(next);
}
}
}
return -1;
}
int main()
{
//freopen("in.txt", "r", stdin);
while(scanf("%d %d", &n, &m) == 2 && n+m)
{
char s[maxn];
for(int i = 0; i < n; i++)
{
scanf("%s", s);
for(int j = 0; j < m; j++)
{
a[i][j].x = i;
a[i][j].y = j;
a[i][j].c = s[j];
}
}
memset(vis, 0, sizeof(vis));
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);
int t = 1;
int x = 0, y = 0;
int fx = a[x][y].x, fy = a[x][y].y;
while(t <= ans)
{
fx = a[x][y].x;
fy = a[x][y].y;
printf("%ds:(%d,%d)->(%d,%d)\n", t++, x, y, fx, fy);
if(a[fx][fy].c >= '0' && a[fx][fy].c <= '9')
for(int i = 0; i < a[fx][fy].c - '0'; i++)
printf("%ds:FIGHT AT (%d,%d)\n",t++, fx, fy);
x = fx;
y = fy;
}
}
printf("FINISH\n");
}
}