[NOIP2002 普及组] 过河卒
题目描述
棋盘上 A 点有一个过河卒,需要走到目标 B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C
点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,A 点 (0,0)、B 点 (n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 A 点能够到达 B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 B 点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
样例 #1
样例输入 #1
样例输出 #1
提示
对于 100% 的数据,1≤n,m≤20,0≤ 马的坐标 ≤20。
【题目来源】
NOIP 2002 普及组第四题
思路
这道题是2002年普及组第四题,所以难度不高,看到这道题,很容易想到是一个动态规划,那就好解了,唯一区别就是额外处理一下马的位置就行,用DP不会超时,如果跟走迷宫一样从(
0,0)走,会超时。
代码
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; int n, m, house_vis[25][25], h_n, h_m; ll ans; ll f[25][25]; int house[8][2] = {{2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}, {1, -2}, {2, -1}}; bool in_mg(int x, int y) { return x >= 0 && x <= n && y >= 0 && y <= m && house_vis[x][y]!=1; } ll dfs(int x, int y) { if (!in_mg(x,y)) return 0; if (x == 0 && y == 0) return 1; if (f[x][y] != -1) return f[x][y]; f[x][y] = dfs(x - 1, y) + dfs(x, y - 1); return f[x][y]; } int main() { cin >> n >> m >> h_n >> h_m; house_vis[h_n][h_m] = 1; for (int i = 0; i < 25; ++i) { for (int j = 0; j < 25; ++j) { f[i][j] = -1; } } for (int i = 0; i < 8; i++) { int No_x = h_n + house[i][0]; int No_y = h_m + house[i][1]; if (in_mg(No_x, No_y)) house_vis[No_x][No_y] = 1; } ans = dfs(n,m); cout<<ans; return 0; }
|