题目就不介绍了,自己找找就行了,应该比较容易找到。
看到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; } //第一次发,废话太多请见谅