洛谷题解 P1002 【过河卒】
题目描述
棋盘上$A$点有一个过河卒,需要走到目标$B$点。卒行走的规则:可以向下、或者向右。同时在棋盘上$C$点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,$A$点$(0, 0)$、$B$点$(n, m)$($n$, $m$为不超过$20$的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从$A$点能够到达$B$点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入输出格式
输入格式:
一行四个数据,分别表示$B$点坐标和马的坐标。
输出格式:
一个数据,表示所有的路径条数。
输入输出样例
输入样例#1:
6 6 3 3
输出样例#1:
6
说明
结果可能很大!
看到题目二话不说用了搜索,直到在提交前看了一下算法标签,又看了一下数据范围。。。
状态转移方程的推导并不复杂,每次判断卒是否能走到这个格子,不可以则为0(显而易见),可以则为下方与左方的值之和。
上代码,这道题算是一道DP入门题吧。
#include<stdio.h>
const int MAXN = 20 + 5;
const int attack[9][2] = {{0, 0}, {1, 2}, {2, 1}, {-1, 2}, {2, -1}, {1, -2}, {-2, 1}, {-1, -2}, {-2, -1}};
long long dist[MAXN][MAXN];
int map[MAXN][MAXN];
int n, m, x, y;
void init(void) {
for(int i = 0; i < 9; i++) {
if(x + attack[i][0] <= n && x + attack[i][0] >= 0) {
if(y + attack[i][1] <= m && y + attack[i][1] >= 0) {
map[x + attack[i][0]][y + attack[i][1]] = true;
}
}
}
}
int main() {
scanf("%d%d%d%d", &n, &m, &x, &y);
init();
int k = 1;
for(int i = 0; i <= n; i++) {
dist[i][0] = map[i][0] ? k = 0 : k;
}
k = 1;
for(int i = 0; i <= m; i++) {
dist[0][i] = map[0][i] ? k = 0 : k;
}
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= m; j++) {
dist[i][j] = map[i][j] ? 0 : dist[i - 1][j] + dist[i][j - 1];
}
}
printf("%lld\n", dist[n][m]);
return 0;
}
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 许可协议。转载请注明出处!
本文链接:https://keepthethink.github.io/archives/2197869946/