题目描述
棋盘上 𝐴A 点有一个过河卒,需要走到目标 𝐵B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 𝐶C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示,𝐴A 点 (0,0)(0,0)、𝐵B 点 (𝑛,𝑚)(n,m),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 𝐴A 点能够到达 𝐵B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入格式
一行四个正整数,分别表示 𝐵B 点坐标和马的坐标。
输出格式
一个整数,表示所有的路径条数。
输入输出样例
输入
6 6 3 3
输出
6
说明/提示
对于 100%100% 的数据,1≤𝑛,𝑚≤201≤n,m≤20,0≤0≤ 马的坐标 ≤20≤20。
【题目来源】
题解
思路
首先这题卒只有向下和向右两个方向走,遇到马能到的位置,不能走
我们会发现如下图,当我们到达(1,1)这个点的时候
可以是(0,0)右走在下 也可以是(0,0)下走向右
在通过(2,1)一样会发现
路线条数为(到达上面个点的条数加上到达左边个点的条数)
因此状态转移方程为graph[i][j] = max(graph[i][j], graph[i - 1][j] + graph[i][j - 1[]);
这是我一开始的代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 30;
long long graph[N][N];
//8个方向的x和y
int dx[] = {-1, -2, -2, -1, 1, 2, 2, 1};
int dy[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int v[N][N];//用来标记马的位置和马会到的位置
int main(){
int n, m, mx, my;
cin >> n >> m >> mx >> my;
memset(graph, 0, sizeof graph);
memset(v, 1, sizeof v);
//第一个点为1
graph[0][0] = 1;
v[mx][my] = 0;//马的位置不能走
for (int i = 0; i < 8; i ++){
v[mx + dx[i]][my + dy[i]] = 0;//马能到的点不能走
}
long long top,left;//越界的用途
for (int i = 0; i <= n; i ++){
for (int j = 0; j <= m; j ++){
if (!v[i][j])//如果是马在的地方就跳过
continue;
if(i - 1 < 0) top = 0;//如果越界,说明左边为0
else top = graph[i - 1][j];
if (j - 1 < 0) left = 0;//越界上面为0
else left = graph[i][j - 1];
graph[i][j] = max(graph[i][j], top + left);//找最大值给当前这个点
}
}
cout << graph[n][m];
return 0;
}
会发现 我会花一些其他的东西来防止越界,最后我发现可以整体移动一位,就能够房子越界
我更新后的代码为下面这个
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 30;
long long graph[N][N];
int dx[] = {-1, -2, -2, -1, 1, 2, 2, 1};
int dy[] = {-2, -1, 1, 2, 2, 1, -1, -2};
int v[N][N];
int main(){
int n, m, mx, my;
cin >> n >> m >> mx >> my;
memset(graph, 0, sizeof graph);
memset(v, 1, sizeof v);
graph[1][1] = 1;
n ++, m ++, mx ++, my ++;//整体移动一位后,上面个左边的边界就不会越界,都是为0
v[mx][my] = 0;
for (int i = 0; i < 8; i ++){
v[mx + dx[i]][my + dy[i]] = 0;
}
for (int i = 1; i <= n; i ++){
for (int j = 1; j <= m; j ++){
if (!v[i][j])
continue;
graph[i][j] = max(graph[i][j], graph[i - 1][j] + graph[i][j - 1]);
}
}
cout << graph[n][m];
return 0;
}