这道题是在晚上睡不着的时候做的。。。然后,就早上辣 (太弱啦~~(>_<)~~
这道题用普通的队列存是不行的,因为存在monster,打怪兽需要时间,所以即使步数相同,打怪耗时也不同。假设存在两条都能到达目标的路,但是由于monster需要耗费时间,所以需要将队列中的成员按照耗时的大小进行从小到大的排序,这样,当到达终点时所选取的路径就是耗时最少的了。
所以,考虑使用可以对成员进行排序的优先队列来操作。。。这里涉及到一个运算符的重载问题,关于运算符重载的构造我写在了小贴士里边,蛮简单的。
贴上链接:优先队列中重载运算符>和<
另外,这道题需要记录路径,之前是想用栈来存数据的,然后发现如果倒着搜索的话就不用这么麻烦的一个个的弹栈辣,所以是从终点开始搜索的=。=然后开一个数组来记录每一个坐标的前驱,然后用循环迭代将每个对应的坐标进行输出。
另外还有一些小细节多WA几次就发现辣TAT
代码如下:
#include<iostream>
#include<queue>
#include<cstring>
#define M 105
using namespace std;
int n,m;
char map[M][M];
int vis[M][M];
struct node
{
int x, y, step;
friend bool operator < (node a, node b)
{
return a.step > b.step;
}
};
struct pre
{
int x, y;
};
pre pre[M][M];
int dr[4][2] = {{-1,0}, {1,0}, {0, -1}, {0, 1}};
void bfs(int end_x, int end_y)
{
node end;
end.x = end_x;
end.y = end_y;
vis[end_x][end_y] = 1;
pre[end_x][end_y].x = 233333;
pre[end_x][end_y].y = 233333;
if (map[end_x][end_y] != '.')
end.step = map[end_x][end_y] - '0';
else
end.step = 0;
priority_queue<node> q;
q.push(end);
while (!q.empty())
{
node temp = q.top();
q.pop();
if (temp.x == 0 && temp.y == 0)
{
int count = 1;
printf("It takes %d seconds to reach the target position, let me show you the way.\n",temp.step);
while (temp.x != end_x || temp.y != end_y)
{
printf("%ds:(%d,%d)->(%d,%d)\n",count++, temp.x, temp.y, pre[temp.x][temp.y].x, pre[temp.x][temp.y].y);
if (map[pre[temp.x][temp.y].x][pre[temp.x][temp.y].y] != '.')
{
int c = map[pre[temp.x][temp.y].x][pre[temp.x][temp.y].y] - '0';
while (c--)
{
printf("%ds:FIGHT AT (%d,%d)\n", count++, pre[temp.x][temp.y].x, pre[temp.x][temp.y].y);
}
}
int num = temp.x;
temp.x = pre[temp.x][temp.y].x;
temp.y = pre[num][temp.y].y;
}
return;
}
int x, y;
for (int i=0; i<4; i++)
{
node save = temp;
x = temp.x + dr[i][0];
y = temp.y + dr[i][1];
if (x>=0 && x<n && y>=0 && y<m)
{
if (!vis[x][y])
{
if (map[x][y] != 'X')
{
vis[x][y] = 1;
pre[x][y].x = temp.x;
pre[x][y].y = temp.y;
save.x = x;
save.y = y;
if (map[x][y] != '.')
save.step = temp.step + map[x][y] - '0' + 1;
else
save.step = temp.step + 1;
q.push(save);
}
}
}
}
}
printf("God please help our poor hero.\n");
}
int main()
{
while (~scanf("%d %d",&n, &m))
{
memset(map,0,sizeof(map));
memset(vis,0,sizeof(vis));
for (int i=0; i<n; i++)
cin >> map[i];
bfs(n-1, m-1);
printf("FINISH\n");
}
return 0;
}
自己真的是太弱辣,求各位巨巨的指点QAQ。。。。。