鸣人与佐助

题目要求如下:

已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费 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数组,因此应该是三维数组

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值