1. 问题分析与算法设计思路
过河卒问题是一个经典的动态规划题目,它模拟了中国象棋中卒子的移动规则,并加入了马的控制点限制条件。这个问题的核心在于计算从起点到终点的所有可能路径数,同时避开被对方马控制的格子。
1.1 问题建模
我们可以将棋盘看作一个二维坐标系,其中:
- 起点A固定在(0,0)
- 终点B在(n,m)
- 对方马的位置在(ax,ay)
卒子的移动规则是只能向右或向下移动,而马的控制点包括马本身的位置以及马一步能跳到的8个位置(中国象棋中马的走法是"日"字形)。
1.2 动态规划思路
解决这个问题的关键在于建立状态转移方程。我们定义f[i][j]表示从起点(0,0)到达点(i,j)的路径数量。根据卒子的移动规则,可以得到以下状态转移方程:
f[i][j] = f[i-1][j] + f[i][j-1]
当然,这个方程的前提是(i,j)不是马的控制点,且i和j都不为0(边界情况需要特殊处理)。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 算法实现细节
2.1 数据结构设计
我们需要两个二维数组:
- vis数组:标记马的控制点,1表示控制点,0表示非控制点
- f数组:存储到达每个点的路径数
cpp复制vector<vector<long long>> f(m+1, vector<long long>(n+1)); // 路径数数组
vector<vector<long long>> vis(m+1, vector<long long>(n+1)); // 控制点标记数组
使用long long类型是为了防止大数溢出,因为当n和m较大时(接近20),路径数可能非常大。
2.2 马控制点的计算
马可以移动到8个方向的位置,我们需要检查这些位置是否在棋盘范围内:
cpp复制vector<int> dx = { -2,-2,-1,-1,1,1,2,2 }; // 马移动的x方向
vector<int> dy = { -1,1,2,-2,2,-2,1,-1}; // 马移动的y方向
vis[ay][ax] = 1; // 马本身的位置
for (int i = 0; i < 8;i++) {
long long cx = ax + dx[i];
long long cy =
