奕哥今天玩到一款寻宝游戏,地图是一个n*m的矩阵,其中分布着一些宝藏,每个宝藏具有一定的价值,奕哥只能拿走其中一个宝藏。奕哥起始在a行b列。奕哥可以向相邻的一格移动,但不能走出地图外。奕哥初始体力值X,移动一格需要消耗体力值为1。体力耗尽后奕哥无法继续移动。地图中有一些障碍物,奕哥无法移动到障碍物上。奕哥想知道他能拿到的最具价值的宝藏是哪一个。
输入格式:
第一行包含5个整数n,m,a,b,X。n,m分别表示地图行数,列数;a,b表示奕哥起始位置在a行b列;X表示奕哥的体力。
( 1<=n,m<=1000, 1<=a<=n, 1<=b<=m, 0<=X<=1e10)
接下来n行,每行m个整数。第i行第j个整数为Aij (-1<=Aij<=1e9)。若Aij=-1,则表示第i行第j列有障碍物;否则表示该位置有一个价值为Aij的宝物。保证起始位置没有障碍物。
输出格式:
奕哥能拿到价值最高的宝藏的价值。
输入样例:
3 3 1 1 3
0 -1 10
3 5 7
-1 8 15
输出样例:
8
代码:
#include<stdio.h>
struct point
{
int x, y;
int step = 0;
};
int main()
{
struct point queue[10000]; int front = 0, rear = 1, max = 0;
int n, m, energy; scanf("%d %d %d %d %d", &n, &m, &queue[0].y, &queue[0].x, &energy);
int map[n + 2][m + 2][2], point_num = 0;
int xx[4] = {-1, 0, 1, 0}; //左上右下
int yy[4] = {0, -1, 0, 1}; //左上右下
for (int i = 1; i <= n; i++) // 输入宝藏值,
for (int j = 1; j <= m; j++)
{
scanf("%d", &map[i][j][0]);
map[i][j][1] = 0; // 赋值为0,表示未走过.
}
map[queue[0].y][queue[0].x][1] = 1; // 起点标记为走过
while (front != rear && queue[front].step <= energy)
{
// 比较当前节点的宝藏值和最大宝藏值的大小,取大的赋值给最大值.
max = (max < map[queue[front].y][queue[front].x][0]) ? map[queue[front].y][queue[front].x][0] : max;
// 如果步数等于体力值,就不要判增加到的点了,节省点时间.
if (queue[front].step == energy) {front++; continue;}
for (int i = 0; i < 4; i++)
{
// 去往的点的坐标dx dy
int dx = queue[front].x + xx[i];
int dy = queue[front].y + yy[i];
// 如果这点符合规范(dxdy在地图范围内,且dx,dy没被走过,且不为墙)
if (dx >= 1 && dx <= m && dy >= 1 && dy <= n && map[dy][dx][1] == 0 && map[dy][dx][0] != -1)
{
map[dy][dx][1] = 1; // 标记为走过
queue[rear].x = dx; // 记录新点
queue[rear].y = dy;
queue[rear++].step = queue[front].step + 1; // 记录步数
}
if (rear >= 10000) rear = 0; // 环形队列的
}
if (++front >= 10000) front = 0; // 环形队列的
}
printf("%d", max); // 输出最大值
return 0;
}
总结:
一道BFS的题
这道题没有终点,思路就是先bfs搜一下能到达的点,取能到的点的宝藏的最大值即可.
这里需要注意的是,上面的 n m 是行和列,转换过来成我习惯的表达方式就是 y x.
且因为地图可以很大,所以整了个环形队列.