Magicpig 拯救 Amaze
题目:Magicpig 拯救 Amaze(原始森林迷宫)
题目背景
原始森林中有很多树,如线段树、后缀树和红黑树等,你掌握了所有的树吗?别担心,本问题不会谈论树,而是介绍原始森林中的一些动物。
-
第一种是金刚:金刚是一种危险的动物,如果你遇到金刚,你会死的。
-
第二种是野狗:它不像金刚那么危险,但它会咬你,被咬两次之后你也会死的。
Amaze 是一个女孩,她不幸迷失于原始森林中。Magicpig 非常担心她,他要到原始森林找她。Magicpig 知道遇到金刚会死,被野狗咬两次也会死,他是多么可怜!
题目描述
输入的第 1 行是单个数字 t(0 ≤ t ≤ 20),表示测试用例的数目。
每个测试用例:
-
第一行给出一个整数
n(0 ≤ n ≤ 30),表示原始森林是一个n×n的单元矩阵。 -
接下来
n行,每行一个长度为n的字符串,表示地图,其中:-
p表示 Magicpig(起点) -
a表示 Amaze(终点) -
r表示道路(可通行) -
k表示金刚(遇到即死亡,不可通行) -
d表示野狗(遇到会被咬一次,累计被咬两次即死亡)
-
Magicpig 只能在上、下、左、右 4 个方向移动。
对于每个测试用例,如果 Magicpig 能够在存活的前提下找到 Amaze,则输出 Yes,否则输出 No。
输入格式
-
第 1 行:单个整数
t,表示测试用例数。 -
每个测试用例:
-
第 1 行:整数
n。 -
接下来
n行:每行n个字符,表示地图。
-
输出格式
对于每个测试用例,输出一行 Yes 或 No。
输入样例
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 迷宫搜索题,和普通迷宫的区别在于:
-
除了位置,还需要记录当前的被咬次数(0 或 1),因为被咬两次就会死亡,不能再继续移动。
-
遇到金刚
k时,直接死亡,不能通过。 -
遇到野狗
d时,被咬次数 +1,只有当次数 < 2 时才能继续移动。
因此,BFS 的状态需要包含三个信息:(x, y, biteCount),其中 biteCount 表示当前已经被咬的次数(0 或 1)。
解题思路(核心)
-
状态定义:使用三维数组
visited[x][y][bite]记录是否访问过(x,y)位置且被咬bite次的状态,避免重复搜索。 -
队列元素:存储
(x, y, biteCount)。 -
移动规则:
-
遇到
k:直接跳过,不加入队列。 -
遇到
d:如果biteCount == 1,跳过;否则新状态为(nx, ny, 1)。 -
遇到
r或p或a:新状态为(nx, ny, biteCount)。
-
-
终止条件:在 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。
浙公网安备 33010602011771号