一、什么是递归?
递归说的通俗一点就是一个函数自己调用自己的过程。函数某个变量值会按一定规律变化,最终达到某个界限,然后要么停止要么退回到上一层继续运行,直到遍历完所有位置。
二、例题
马走日
给你一个n,m代表棋盘范围(0<n/m<=30)再给你Q点坐标(a,b)和E点坐标(c,d)请你求出起点到终点有几条路可以到(马只能跳上、下右三个方向,保证不向回跳)最后输出k。
输入样例 30 30 1 15 5 15 输出
标红的点是可以跳到的地方
递归题最重要的是递归函数,函数里最重要的是每次返回值的变化过程,每次变量量变量变化都要按照实际情况判断调整。
这个试题中最容易想到的暴力破解方式:
if(a-2>=0&&a-2<=n&&b+1>=m&&b+1<=0){
digui(a-2,b+1);
}
//其余两种一次类推
不过这种办法过于麻烦,用数组简单调整一下,简洁代码
int x[4]={-2,-1,1,2};
int y[4]={1,2,2,1};
for(int i=0;i<4;i++){
if(a+x[i]>=0&&a+x[i]<=n&&b+y[i]>=0&&b+y[i]<=m){
dig(a+x[i],b+y[i]);
}
}
不过还是有不少点存在重复寻找的几率,为了不重复寻找,使用剪枝算法会使程序快速简洁
int n,m,a,b,c,d;
int k[50][50];
int x[4]={-2,-1,1,2};
int y[4]={1,2,2,1};
int tj=0;
int board[50][50];
int digui(int a,int b){
if(a<0 || a>=n || b<0 || b>=m){
return 0;
}//判断是否越界
if(a==c&&b==d){
return 1;
}//判断是否结束
if(board[a][b]!=0){
return board[a][b];
}//判断点是否重复
int tem=0;
for(int i=0;i<=3;i++){
tem += digui(a+x[i],b+y[i]);
}//常规加减
board[a][b] = tem;//累加到board
return tem;
}
三、递归基本模版
int digui(int a,int b){
if(~~~~~~~~){
return 0;
}//结束条件1
if(!=~~~~~~~~){
return 1;
}//结束条件2,没有或者更多条件都行
if($¥%^@~){
digui(a-y,b-y);
}//自己调用自己,继续递归
}
四、结束条件
if(~~)和for都可以成为结束条件
五、组成
自己用自己