题目描述
棋盘上 A 点有一个过河卒,需要走到目标 B 点。卒行走的规则:可以向下、或者向右。同时在棋盘上 C 点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。因此称之为“马拦过河卒”。
棋盘用坐标表示, A 点 (0, 0) 、 BB 点 (n, m)( n, m 为不超过 20 的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从 A 点能够到达 B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入输出格式
输入格式:
一行四个数据,分别表示 B点坐标和马的坐标。
输出格式:
一个数据,表示所有的路径条数。
输入输出样例
输入样例#1: 6 6 3 3 | 输出样例#1: 6 |
---|
说明
结果可能很大!
题解: 对于边缘
dp[i][0]=dp[i−1][0]
d
p
[
i
]
[
0
]
=
d
p
[
i
−
1
]
[
0
]
和
dp[0][i]=dp[0][i−1]
d
p
[
0
]
[
i
]
=
d
p
[
0
]
[
i
−
1
]
对于中间
dp[i][j]=dp[i−1][j]+dp[i][j−1];
d
p
[
i
]
[
j
]
=
d
p
[
i
−
1
]
[
j
]
+
d
p
[
i
]
[
j
−
1
]
;
#include <bits/stdc++.h>
using namespace std;
long long dp[40][40],flag[40][40];
int dx[]={1,1,-1,-1,2,2,-2,-2};
int dy[]={2,-2,2,-2,1,-1,1,-1};
int main()
{
int n,m,x,y;
scanf("%d%d%d%d",&n,&m,&x,&y);
memset(flag,0, sizeof(flag));
memset(dp,0, sizeof(dp));
dp[0][0]=1;
for (int i = 0; i <8 ; ++i) {
int kx=x+dx[i];
int ky=y+dy[i];
if(kx>=0&&kx<=n&&ky>=0&&ky<=m&&!flag[kx][ky])
flag[kx][ky]=1;
}
flag[x][y]=1;
for (int i = 1; i <=n ; ++i) {
if(flag[i][0]==0)dp[i][0]=dp[i-1][0];
else
break;
}
for (int i = 1; i <=m ; ++i) {
if(flag[0][i]==0) dp[0][i]=dp[0][i-1];
else break;
}
for (int i = 1; i <=n ; ++i) {
for (int j = 1; j <=m ; ++j) {
if(flag[i][j]==1) continue;
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
printf("%lld\n",dp[n][m]);
return 0;
}