题目要求如下:
已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费 11 个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?
输入输出要求:
核心思想:显然求最短路径要用BFS,只不过扩展层次的时候有特殊要求
代码如下:说明:这样开数组只有做题的平台能开,自己的vc不允许开这么大的数组,会stack overflow
#include<stdio.h>
int M, N, T;
char a[210][210];
int vis[210][210][10];
int step[4][2] = { {1,0},{0,-1},{-1,0},{0,1} };
int sx, sy;
int ex, ey;
typedef struct qu {
int x;
int y;
int z;//代表当前存在的查克拉数量
int t;//花费的时间
}Qu;
int in(int i, int j)
{
return i >= 0 && i < M&& j >= 0 && j < N;
}
int main()
{
scanf("%d %d %d", &M, &N, &T);
for (int i = 0; i < M; i++) scanf("%s", a[i]);
for (int i = 0; i < M; i++) {
for (int j = 0; j < N; j++) {
if (a[i][j] == '@') {
sx = i;
sy = j;
}
if (a[i][j] == '+') {
ex = i;
ey = j;
}
}
}
Qu q[400010];
int front, rear;
front = rear = -1;
rear++;
q[rear].x = sx;
q[rear].y = sy;
q[rear].t = 0;
q[rear].z = T;
vis[sx][sy][T] = 1;
while (front < rear) {
front++;
Qu now = q[front];
if (now.x == ex && now.y == ey) {
printf("%d", now.t);
return 0;
}
for (int i = 0; i < 4; i++) {
Qu next;
next.x = now.x + step[i][0];
next.y = now.y + step[i][1];
next.t = now.t + 1;
if (in(next.x, next.y)) {
if ((a[next.x][next.y] == '*' || a[next.x][next.y] == '+') && !vis[next.x][next.y][now.z]) {
next.z = now.z;
rear++;
q[rear] = next;
vis[next.x][next.y][next.z] = 1;
}
else if (a[next.x][next.y] == '#' && now.z > 0&&!vis[next.x][next.y][now.z-1]) {
next.z = now.z - 1;
rear++;
q[rear] = next;
vis[next.x][next.y][next.z] = 1;
}
}
}
}
printf("-1");
return 0;
}
遇到的问题:
对vis数组的理解,可以这样理解,对于所有的情况,可以看成行,列,以及查克拉的排列组合,也就是M*N*T,所以对于每一种状态都应该有vis数组,因此应该是三维数组