Magicpig 拯救 Amaze

题目:Magicpig 拯救 Amaze(原始森林迷宫)

题目背景

原始森林中有很多树,如线段树、后缀树和红黑树等,你掌握了所有的树吗?别担心,本问题不会谈论树,而是介绍原始森林中的一些动物。

  • 第一种是金刚:金刚是一种危险的动物,如果你遇到金刚,你会死的。

  • 第二种是野狗:它不像金刚那么危险,但它会咬你,被咬两次之后你也会死的。

Amaze 是一个女孩,她不幸迷失于原始森林中。Magicpig 非常担心她,他要到原始森林找她。Magicpig 知道遇到金刚会死,被野狗咬两次也会死,他是多么可怜!


题目描述

输入的第 1 行是单个数字 t0 ≤ t ≤ 20),表示测试用例的数目。

每个测试用例:

  • 第一行给出一个整数 n0 ≤ n ≤ 30),表示原始森林是一个 n×n 的单元矩阵。

  • 接下来 n 行,每行一个长度为 n 的字符串,表示地图,其中:

    1. p 表示 Magicpig(起点)

    2. a 表示 Amaze(终点)

    3. r 表示道路(可通行)

    4. k 表示金刚(遇到即死亡,不可通行)

    5. d 表示野狗(遇到会被咬一次,累计被咬两次即死亡)

Magicpig 只能在上、下、左、右 4 个方向移动。

对于每个测试用例,如果 Magicpig 能够在存活的前提下找到 Amaze,则输出 Yes,否则输出 No


输入格式

  • 第 1 行:单个整数 t,表示测试用例数。

  • 每个测试用例:

    • 第 1 行:整数 n

    • 接下来 n 行:每行 n 个字符,表示地图。

输出格式

对于每个测试用例,输出一行 YesNo


输入样例

4
3
pkk
rrd
rda
3
prr
kkk
rra
4
prrr
rrrr
rrrr
arrr
5
prrrr
ddddd
ddddd
rrrrr
rrrra

输出样例

Yes
No
Yes
No

题目分析

这是一道典型的带状态的 BFS 迷宫搜索题,和普通迷宫的区别在于:

  1. 除了位置,还需要记录当前的被咬次数(0 或 1),因为被咬两次就会死亡,不能再继续移动。

  2. 遇到金刚 k 时,直接死亡,不能通过。

  3. 遇到野狗 d 时,被咬次数 +1,只有当次数 < 2 时才能继续移动。

因此,BFS 的状态需要包含三个信息:(x, y, biteCount),其中 biteCount 表示当前已经被咬的次数(0 或 1)。


解题思路(核心)

  1. 状态定义:使用三维数组 visited[x][y][bite] 记录是否访问过 (x,y) 位置且被咬 bite 次的状态,避免重复搜索。

  2. 队列元素:存储 (x, y, biteCount)

  3. 移动规则

    • 遇到 k:直接跳过,不加入队列。

    • 遇到 d:如果 biteCount == 1,跳过;否则新状态为 (nx, ny, 1)

    • 遇到 rpa:新状态为 (nx, ny, biteCount)

  4. 终止条件:在 BFS 过程中,只要到达 a 的位置,就直接返回 Yes


完整代码(Java)



复杂度分析

  • 时间复杂度O(t × n²),每个测试用例最多访问 n×n×2 个状态(每个位置两种被咬次数),因此总时间为 O(t × n²)

  • 空间复杂度O(n²),三维访问数组和队列的空间开销。


样例解释

  • 第 1 个样例:Magicpig 可以通过 p → r → r → d → a 的路径,被咬一次,成功找到 Amaze → Yes

  • 第 2 个样例:起点右侧就是金刚,无法通行 → No

  • 第 3 个样例:道路全通,直接走到终点 → Yes

  • 第 4 个样例:起点到终点之间有两行野狗,无论怎么走都会被咬两次 → No


posted @ 2026-05-17 03:20  kitic  阅读(1)  评论(0)    收藏  举报