← 返回题目页

P1002 [NOIP 2002 普及组] 过河卒

标程

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m, hx, hy;
    cin >> n >> m >> hx >> hy;

    // 马的 8 个「日」字位置
    const int dx[8] = {1, 1, -1, -1, 2, 2, -2, -2};
    const int dy[8] = {2, -2, 2, -2, 1, -1, 1, -1};

    bool blocked[25][25] = {};
    blocked[hx][hy] = true;                 // 马自己所在的点
    for (int i = 0; i < 8; i++) {
        int x = hx + dx[i], y = hy + dy[i];
        if (x >= 0 && x <= n && y >= 0 && y <= m) blocked[x][y] = true;
    }

    long long dp[25][25] = {};                // 路径数可能超过 int 范围
    dp[0][0] = 1;                            // 起点:1 条空路径

    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            if (blocked[i][j]) continue;     // 马的控制点:dp 保持 0
            if (i == 0 && j == 0) continue;   // 起点已经赋值
            dp[i][j] = (i > 0 ? dp[i - 1][j] : 0) + (j > 0 ? dp[i][j - 1] : 0);
        }
    }

    cout << dp[n][m] << "\n";
    return 0;
}

动画演示