洛谷P2385 [USACO07FEB] Bronze Lilypad Pond B

P2385 [USACO07FEB] Bronze Lilypad Pond B

题目描述

为了让奶牛们娱乐和锻炼,农夫约翰建造了一个美丽的池塘。这个长方形的池子被分成了 M 行 N 列个方格(1 ≤ M, N ≤ 30) 。一些格子是坚固得令人惊讶的莲花,还有一些格子是岩石,其余的只是美丽、纯净、湛蓝的水。

贝西正在练习芭蕾舞,她站在一朵莲花上,想跳到另一朵莲花上去,她只能从一朵莲花跳到另一朵莲花上,既不能跳到水里,也不能跳到岩石上。

贝西的舞步很像象棋中的马步:每次总是先横向移动 M1 (1 ≤ M1 ≤ 30)格,再纵向移动 M2 (1 ≤ M2 ≤ 30, M1≠M2)格,或先纵向移动 M1 格,再横向移动 M2 格。最多时,贝西会有八个移动方向可供选择。

给定池塘的布局和贝西的跳跃长度,请计算贝西从起点出发,到达目的地的最小步数,我们保证输入数据中的目的地一定是可达的。

输入格式

第一行:四个用空格分开的整数:M,N,M1 和 M2

第二行到 M + 1 行:第 i + 1 行有 N 个用空格分开的整数,描述了池塘第

i 行的状态:0 为水,1 为莲花,2 为岩石,3 为贝西所在的起点,4 为贝西想去

的终点。

输出格式

第一行:从起点到终点的最少步数。

输入输出样例 #1

输入 #1

4 5 1 2
1 0 1 0 1
3 0 2 0 4
0 1 2 0 0
0 0 0 1 0

输出 #1

2

又是一个关于最短路径的问题,结合了前几次做的题目要素,包括马走日问题,迷宫障碍等

具体来看,类似马走日的走法,只不过本题的步子大小不确定,输入决定
那么

点击查看代码
int dx[8],dy[8];
void get_dir(){
    int idx[8] = {M1, M1, -M1, -M1, M2, M2, -M2, -M2};
    int idy[8] = {M2, -M2, M2, -M2, M1, -M1, M1, -M1};
    for (int i = 0; i < 8; ++i) {
        dx[i] = idx[i];
        dy[i] = idy[i];
    }
}
我们先定义根据步子大小而改变的坐标改变的数组,将里面的元素全部用M1和M2来表示,再通过main函数中的调用获得具体的大小依次给数组的元素重新赋值,就相当于马走日问题中直接赋值了

完整代码如下

点击查看代码
#include <stdio.h>
#include <string.h>

#define MAXN 32

typedef struct {
    int x, y, step;
} Node;

int n, m, M1, M2;
int map[MAXN][MAXN];
int visited[MAXN][MAXN];

int dx[8],dy[8];
void get_dir(){
    int idx[8] = {M1, M1, -M1, -M1, M2, M2, -M2, -M2};
    int idy[8] = {M2, -M2, M2, -M2, M1, -M1, M1, -M1};
    for (int i = 0; i < 8; ++i) {
        dx[i] = idx[i];
        dy[i] = idy[i];
    }
}

int BFS(int sx, int sy, int ex, int ey) {
    Node queue[MAXN * MAXN * 4];
    int front = 0, rear = 0;
    queue[rear++] = (Node){sx, sy,0};
    visited[sx][sy] = 1;

    while (front < rear) {
        Node now = queue[front++];
        if(now.x == ex && now.y == ey)
            return now.step; //到达终点返回步数

        for (int i = 0; i < 8; ++i) {
            int nx = now.x + dx[i];
            int ny = now.y + dy[i];

            if(!visited[nx][ny] && //未访问
            nx >= 0 && nx <= m && ny >= 0 && ny <= n //未越界
            && (map[nx][ny] == 1 || map[nx][ny] == 4)){ //可以走
                visited[nx][ny] = 1;
                queue[rear++] = (Node){nx, ny, now.step + 1};
            }
        }
    }
    return -1;
}
int main() {
    scanf("%d %d %d %d", &m, &n, &M1, &M2);
    int sx, sy, ex, ey;
    int i, j;
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            scanf("%d", &map[i][j]);
            if (map[i][j] == 3) {
                sx = i;
                sy = j;
            } else if (map[i][j] == 4) {
                ex = i;
                ey = j;
            }
        }
    }
    get_dir();
    int result = BFS(sx, sy, ex, ey);
    printf("%d\n", result);
    return 0;
}
posted @ 2025-05-09 23:58  sirro1uta  阅读(17)  评论(0)    收藏  举报