1. 题目解析与算法选择
这道题目来自AtCoder Beginner Contest 246的E题,题目名为"Bishop 2"。题目描述了一个棋盘上的象移动问题:给定一个N×N的棋盘,其中某些格子是障碍物(用'#'表示),空白格子用'.'表示。我们需要计算象从起点(si, sj)到终点(ti, tj)所需的最少移动次数,如果无法到达则输出-1。
1.1 题目特点分析
象在国际象棋中的移动规则是沿对角线方向任意格数移动。这道题的特殊之处在于:
- 棋盘上存在障碍物,象不能穿过障碍物
- 每次改变移动方向算作一次新的移动
- 沿着同一方向连续移动不增加移动次数
这些特点使得传统的BFS算法不能直接应用,因为:
- 普通BFS会将每次移动都视为一步,无法处理"同一方向连续移动不算新步数"的规则
- 需要记录移动方向信息来判断是否改变方向
1.2 算法选择思路
针对这个问题,我们考虑以下几种算法方案:
-
普通BFS:
- 无法区分方向变化,会错误计算步数
- 时间复杂度O(n²),但无法得到正确结果
-
Dijkstra算法:
- 可以处理不同权重的边
- 但时间复杂度O(n² log n),对于n≤1500来说可能不够高效
-
分层图+01BFS:
- 将每个格子拆分为4个状态,代表4个移动方向
- 同方向移动边权为0,改变方向边权为1
- 时间复杂度O(4n²),空间复杂度O(4n²)
- 完美匹配题目特性
经过比较,我们选择分层图+01BFS的方案,因为它:
- 准确反映了题目中的移动规则
- 保持了较高的效率
- 实现相对简洁
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 分层图设计与01BFS原理
2.1 分层图设计
分层图的核心思想是将原问题中的每个物理位置拆分为多个逻辑状态。在这个问题中,我们为每个格子(i,j)创建4个状态,对应4个对角线移动方向:
- 左上方向(dx=-1, dy=-1)
- 右上方向(dx=-1, dy=1)
- 左下方向(dx=1, dy=-1)
- 右下方向(dx=1, dy=1)
这样,整个图就变成了一个四层的结构,每个物理位置对应4个节点。
2.2 状态转移规则
在分层图中,我们定义两种转移:
