题目就不介绍了,自己找找就行了,应该比较容易找到。
看到A点和B点的坐标范围就可以求出数组的行列范围了(用来存储每一个点到达点B的路径数);为防止马的拦截点跑出去,需要将出发点A(0,0)转化为数组中的(1,1),这个时候要稍微调整遍历范围,记得要开到23格。由于数据可能较大,数组类型用long long(亲测有效)。 因为卒的移动只能是向下一格或者向右一格,所有要到达B(n,m),就必须要到达(n-1,m)或(n,m-1),而到达这两个点的路径数也同样可以这样一直类推下去。 其状态转移方程为f(n,m)=f(n-1,m)+f(n,m-1) 然后将路径数记忆化。 最后直接输出就行
#include<iostream>
using namespace std;
long long a[23][23];//int型会溢出
int main()
{
for(int i=0;i<23;i++)
for(int j=0;j<23;j++)
a[i][j]=1;
//本来只需要初始第n+1行和m+1列的(都处于边界,只有一种走法),但是我突然忘了怎么弄,就全部初始化为1了。由于在后面的求解过程中我是直接求和的,会覆盖原来的1,所以也能得到正解。
int n,m;
int c,b;//分别为行和列
cin>>c>>b;//B点的坐标
cin>>n>>m;//马的坐标
n++,m++;//出发点发生变化,需要调整B的坐标
a[n][m]=a[n+1][m-2]=a[n+2][m-1]=a[n+1][m+2]=a[n+2][m+1]=a[n-1][m-2]=a[n-2][m-1]=a[n-2][m+1]=a[n-1][m+2]=0;
//初始化拦截点
for(int i=b;i>=1;--i)/*b,c都不需要-1,原因和B一样 */
{
for(int j=c;j>=1;--j)
{
if(a[j][i]) a[j][i]=a[j][i+1]+a[j+1][i];//判断是否可以走
}
}
/*由于我是倒着来的,即由终点到起点,所以这个部分和其他几个大佬不一样,但是原理完全相同。*/
cout<<a[1][1];
return 0;
}
//第一次发,废话太多请见谅