AcWing 188:武士风度的牛 ← BFS

【题目来源】
https://www.acwing.com/problem/content/190/

【题目描述】
农民 John 有很多牛,他想交易其中一头被 Don 称为 The Knight 的牛。
这头牛有一个独一无二的超能力,在农场里像 Knight 一样地跳(就是我们熟悉的象棋中马的走法)。
虽然这头神奇的牛不能跳到树上和石头上,但是它可以在牧场上随意跳,我们把牧场用一个 x,y 的坐标图来表示。
这头神奇的牛像其它牛一样喜欢吃草,给你一张地图,上面标注了 The Knight 的开始位置,树、灌木、石头以及其它障碍的位置,除此之外还有一捆草。
现在你的任务是,确定 The Knight 要想吃到草,至少需要跳多少次。
The Knight 的位置用 K 来标记,障碍的位置用 * 来标记,草的位置用 H 来标记。
这里有一个地图的例子:

cpp 复制代码
             11 | . . . . . . . . . .
             10 | . . . . * . . . . . 
              9 | . . . . . . . . . . 
              8 | . . . * . * . . . . 
              7 | . . . . . . . * . . 
              6 | . . * . . * . . . H 
              5 | * . . . . . . . . . 
              4 | . . . * . . . * . . 
              3 | . K . . . . . . . . 
              2 | . . . * . . . . . * 
              1 | . . * . . . . * . . 
              0 ----------------------
                                    1 
                0 1 2 3 4 5 6 7 8 9 0

The Knight 可以按照下图中的 A,B,C,D... 这条路径用 5 次跳到草的地方(有可能其它路线的长度也是 5):

cpp 复制代码
             11 | . . . . . . . . . .
             10 | . . . . * . . . . .
              9 | . . . . . . . . . .
              8 | . . . * . * . . . .
              7 | . . . . . . . * . .
              6 | . . * . . * . . . F<
              5 | * . B . . . . . . .
              4 | . . . * C . . * E .
              3 | .>A . . . . D . . .
              2 | . . . * . . . . . *
              1 | . . * . . . . * . .
              0 ----------------------
                                    1
                0 1 2 3 4 5 6 7 8 9 0

注意: 数据保证一定有解。

【输入格式】
第 1 行: 两个数,表示农场的列数 C 和行数 R。
第 2..R+1 行: 每行一个由 C 个字符组成的字符串,共同描绘出牧场地图。

【输出格式】
一个整数,表示跳跃的最小次数。

【数据范围】
1≤R,C≤150

【输入样例】

cpp 复制代码
10 11
..........
....*.....
..........
...*.*....
.......*..
..*..*...H
*.........
...*...*..
.K........
...*.....*
..*....*..

【输出样例】
5

【算法代码】

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

const int maxn=155;
char g[maxn][maxn];
int dis[maxn][maxn];
typedef pair<int,int> PII;
int dy[8]= {2,1,-1,-2,-2,-1,1,2};
int dx[8]= {1,2,2,1,-1,-2,-2,-1};
int n,m;

int bfs(PII x,PII y) {
    queue<PII> q;
    q.push(x);

    memset(dis,-1,sizeof(dis));
    dis[x.first][x.second]=0;

    while(!q.empty()) {
        PII t=q.front();
        q.pop();
        for(int i=0; i<8; i++) {
            int u=t.first+dx[i];
            int v=t.second+dy[i];
            if(u>=0 && v>=0 && u<n && v<m) {
                if(dis[u][v]==-1 && g[u][v]!='*') {
                    dis[u][v]=dis[t.first][t.second]+1;
                    if(make_pair(u,v)==y) return dis[u][v];
                    q.push({u,v});
                }
            }
        }
    }
    return -1;
}

int main() {
    PII start;
    PII end;
    cin>>m>>n;

    for(int i=0; i<n; i++) {
        for(int j=0; j<m; j++) {
            cin>>g[i][j];
            if(g[i][j]=='K') start= {i,j};
            if(g[i][j]=='H') end= {i,j};
        }
    }

    cout<<bfs(start,end)<<endl;
}


/*
in:
10 11
..........
....*.....
..........
...*.*....
.......*..
..*..*...H
*.........
...*...*..
.K........
...*.....*
..*....*..

out:
5
*/

【参考文献】
https://www.acwing.com/solution/content/60196/
https://www.acwing.com/solution/content/140308/
https://www.acwing.com/solution/content/82258/

相关推荐
是阿建吖!7 天前
【递归、搜索与回溯算法】穷举、暴搜、深搜、回溯、剪枝
算法·bfs·剪枝
CUC-MenG15 天前
2025牛客多校第五场 K.完美旅程 J.最快覆盖问题 E.神秘异或操作 个人题解
数学·dfs·bfs·优先队列·二分·位运算·fmt·曼哈顿距离·fwt
Espresso Macchiato21 天前
Leetcode 3629. Minimum Jumps to Reach End via Prime Teleportation
bfs·广度优先遍历·leetcode medium·leetcode 3629·leetcode周赛460·质数求解·质因素分解
柏箱2 个月前
容器里有10升油,现在只有两个分别能装3升和7升油的瓶子,需要将10 升油等分成2 个5 升油。程序输出分油次数最少的详细操作过程。
算法·bfs
芜湖xin2 个月前
【题解-洛谷】B4292 [蓝桥杯青少年组省赛 2022] 路线
算法·图论·bfs·图的遍历
laufing2 个月前
OD 算法题 B卷【最大岛屿体积】
bfs
无影无踪的青蛙3 个月前
[C++]洛谷B3626 跳跃机器人(题干 + 详细讲解, BFS练习题)
开发语言·c++·算法·bfs·广度优先
GGBondlctrl3 个月前
【leetcode】《BFS扫荡术:如何用广度优搜索征服岛屿问题》
算法·leetcode·bfs·宽度优先·图像渲染·岛屿的数量·被围绕的区域
理想奋斗中3 个月前
【LeetCode Hot100 | 每日刷题】二叉树的层序遍历
算法·leetcode·bfs
Dante7984 个月前
【多源01BFS】Codeforce:Three States
c++·算法·bfs