题目描述
中国象棋半张棋盘如图 所示。马自左下角 (0,0) 向右上角 (m,n) 跳。规定只能往右跳,不准往左跳。比如图 中所示为一种跳行路线,并将路径总数打印出来。
输入格式
只有一行:两个数 n,m。
输出格式
只有一个数:总方案数total。
输入输出样例
输入 #1复制
4 8
输出 #1复制
37
找到搜索起点和边界:起点(0,0),边界(n,m)
找到搜索的方向:右上偏上,右上偏下,右下偏上,右下偏下
对于当前位置: (-2,1) (-1,2) (1,2) (2,1)
则我们定义两个数组分别存储行和列的四种变化(要一一对应),搜索的分支就是四个方向
由于定义了两个数组来存行列变化,所以我们在搜索中对行列分别操作,如果走的这一步出界了:行小于0,行大于n,列小于0,列大于m或走过了,就回到上一步。
#include <bits/stdc++.h>
using namespace std;
int a[20][3]={};
int h[4]={2,1,-1,-2},l[4]={1,2,2,1}; //四个方向
int n,m;
int total=0;
bool v[20][20]={};
void print(){
total++;
return;
}
void dfs(int x){
for(int i=0;i<=3;i++){ //遍历四个方向
a[x][1]=a[x-1][1]+h[i]; //行走一步
a[x][2]=a[x-1][2]+l[i]; //列走一步
if(a[x][1]<0||a[x][1]>n||a[x][2]>m||v[a[x][1]][a[x][2]]==1){ //如果出界
a[x][1]=a[x-1][1]-h[i]; //回到上一步
a[x][2]=a[x-1][2]-l[i];
continue; //跳出,结束这个方案
}
v[a[x][1]][a[x][2]]==1; //走过的位置标记
if((a[x][1]==n)&&(a[x][2]==m)) print(); //如果走到终点,方案累加
else dfs(x+1); //搜索下一步
v[a[x][1]][a[x][2]]==0; //回溯
}
}
int main()
{
a[1][1]=0;a[1][2]=0;//标记初始行列位置为0
cin>>n>>m;
dfs(2); //第一步以确定,从第二部开始搜索
cout<<total;
return 0;
}