考点
题解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f[25][25], ctrl[25][25], n, m, hx, hy;
void init() { ctrl[hx][hy] = 1; for (int i = -2; i <= 2; ++i) for (int j = -2; j <= 2; ++j) if (abs(i) + abs(j) == 3 && (hx + i) >= 0 && (hx + i) <= n && (hy + j) >= 0 && (hy + j) <= m) ctrl[hx + i][hy + j] = 1; }
void run() { for (int i = 0; i <= n; ++i) { for (int j = 0; j <= m; ++j) { if (ctrl[i][j]) continue; if (i - 1 >= 0 && i - 1 <= n) f[i][j] += f[i - 1][j]; if (j - 1 >= 0 && j - 1 <= m) f[i][j] += f[i][j - 1]; } } cout << f[n][m]; }
int main() { f[0][0] = 1; cin >> n >> m >> hx >> hy; init(), run(); return 0; }
|
思路
每次只能向右和向下走,那么每个新的状态就只能由上面一个点和左边一个点共同组成,很容易得到递推式:
\[
f\left( x,y \right) =f\left( x-1,y \right) +f\left( x,y-1 \right)
\]
由于需要避开马的控制范围,所以单独开一个数组ctrl,记录哪些点不能走即可