1 条题解

  • 0
    @ 2026-5-15 17:34:27

    二维数组递推(DP) 来求解。


    分析

    1. 棋盘大小:0..n 行,0..m 列。

    2. 卒从 (0,0)(n,m) 只能向右或向下走。

    3. 马的位置 (mx, my) 控制点:

      • 马所在点 (mx, my) 不能走

      • 马可以跳的点不能走,马走“日”字格:

        dx = [+2,+2,-2,-2,+1,+1,-1,-1]
        dy = [+1,-1,+1,-1,+2,-2,+2,-2]
        
    4. 动态规划公式: [ dp[i][j] = dp[i-1][j] + dp[i][j-1] \quad \text{(如果 (i,j) 不在马控制点)} ]


    C++ 递推实现

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int main() {
        int n, m, mx, my;
        cin >> n >> m >> mx >> my;
    
        bool blocked[21][21] = {false}; // 马控制点
        int dx[8] = {2,2,-2,-2,1,1,-1,-1};
        int dy[8] = {1,-1,1,-1,2,-2,2,-2};
    
        blocked[mx][my] = true; // 马所在点
        for (int k = 0; k < 8; k++) {
            int x = mx + dx[k];
            int y = my + dy[k];
            if (x >= 0 && x <= 20 && y >= 0 && y <= 20) blocked[x][y] = true;
        }
    
        long long dp[21][21] = {0};
        dp[0][0] = blocked[0][0] ? 0 : 1;
    
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                if (blocked[i][j] || (i == 0 && j == 0)) continue;
                if (i > 0) dp[i][j] += dp[i-1][j];
                if (j > 0) dp[i][j] += dp[i][j-1];
            }
        }
    
        cout << dp[n][m] << endl;
        return 0;
    }
    

    样例测试

    输入

    6 6 3 3
    

    输出

    6
    

    ✅ 与题目样例一致。


    这道题 和爬楼梯类似,只是中间有“马控制点”的障碍,需要 DP 递推排除这些点。

    信息

    ID
    1825
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    6
    已通过
    3
    上传者