rt.
本人记忆化搜索 60 pts.
#include <iostream>
#include <vector>
using namespace std;
const int MAXN = 21; // 由于 n, m <= 20
int n, m, horseX, horseY;
bool control[MAXN][MAXN]; // 控制点标记
int dp[MAXN][MAXN]; // 记忆化搜索数组
// 检查一个点是否是马的控制点
bool isControlPoint(int x, int y) {
if (x < 0 || x > n || y < 0 || y > m) return true; // 超出边界
if (x == horseX && y == horseY) return true; // 马所在点
// 马的控制点
int horseMoves[8][2] = {
{1, 2}, {2, 1}, {2, -1}, {1, -2},
{-1, -2}, {-2, -1}, {-2, 1}, {-1, 2}
};
for (int i = 0; i < 8; i++) {
int nx = horseX + horseMoves[i][0];
int ny = horseY + horseMoves[i][1];
if (nx == x && ny == y) return true; // 马的跳跃控制点
}
return false;
}
// 记忆化搜索函数
int countPaths(int x, int y) {
if (x > n || y > m) return 0; // 超出边界
if (isControlPoint(x, y)) return 0; // 是控制点
if (x == n && y == m) return 1; // 到达目标点
if (dp[x][y] != -1) return dp[x][y]; // 如果已经计算过
// 递归计算
dp[x][y] = countPaths(x + 1, y) + countPaths(x, y + 1);
return dp[x][y];
}
int main() {
cin >> n >> m >> horseX >> horseY;
// 初始化控制点标记
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
control[i][j] = false;
}
}
// 计算控制点
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
if (isControlPoint(i, j)) {
control[i][j] = true;
}
}
}
// 初始化 dp 数组
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
dp[i][j] = -1; // -1 表示未计算
}
}
// 计算路径数量
int result = countPaths(0, 0);
cout << result << endl;
return 0;
}