大家好,这里是bang_bang,今天来记录2道递归的典型题目
目录
1.另类加法
2.走方格的方案数
1.另类加法
另类加法__牛客网 (nowcoder.com)
给定两个int A和B。编写一个函数返回A+B的值,但不得使用+或其他算数运算符。
测试样例:
1,2
返回:3
解题思路:在计算十进制加法的时候,我们会将两个数字直接相加,再将相加的结果跟进位相加,最终得到结果,只不过我们人通过长期的训练,不需要如此繁琐,口算就能得到答案,而计算机则不然,他需要根据规则一步一步递归的计算,二进制的加法也是同样如此。
两数相加:
1.直接相加的结果(不考虑进位),不考虑进位的加法用异或(相同为0,不同为1),很好的忽略掉了进位;a^b。
2.得到进位结果(用做跟相加的结果再相加->递归),得到进位用 与运算再左移一位;(a&b)<<1。
3.一直递归的相加,计算进位,止到其中一个计算为0,则最终结果就是另一个数。
举例:
代码如下:
class UnusualAdd {
public:
int addAB(int A, int B) {
if(A==0) return B;
if(B==0) return A; //任意一个为0,则说明另一个就是最终求和结果
int a=A^B;//不考虑进位的相加结果
int b=(A&B)<<1;//得到进位结果
return addAB(a,b);
}
};
2.走方格的方案数
走方格的方案数_牛客题霸_牛客网 (nowcoder.com)
描述
请计算n*m的棋盘格子(n为横向的格子数,m为竖向的格子数)从棋盘左上角出发沿着边缘线从左上角走到右下角,总共有多少种走法,要求不能走回头路,即:只能往右和往下走,不能往左和往上走。
注:沿棋盘格之间的边缘线行走
数据范围: 1≤n,m≤8
输入描述:
输入两个正整数n和m,用空格隔开。(1≤n,m≤8)
输出描述:
输出一行结果
示例1
输入:2 2
输出:6
解题思路:
沿着边缘线行走,可能当n=m=2时,画个图我们还很容易能从起点数到终点有多少条路径,但是当n和m非常大的时候,这时候我们就很难推导了,那么要想把问题简化,我们就要尝试使用递归的思路:
1.一块格子要想从左上角走到右下角,那么必定会经过2个点(右上角和左下角,即右下角相邻的两个点)
2.我们已知走一条直线势必只有一条走法,即边界(最上/最左的边)只有一种走法。
3.我们从终点出发,往回推,到达终点的路径是终点相邻2个点的路径之和,而相邻2个点的路径和,又是他们位于所处位置为右下角的块的相邻2个点的路径之和,依次递归回去,止到问题变成了多个边界点的路径之和。
总结:到达待求结点的路径是其相邻2结点的路径之和,通过递归的方式,往回推,相邻2结点的路径又是他们相邻2结点的路径之和,止到问题变成多个(多个是指从终点往回推,总共经过多少次边界点的数量)边界点的路径之和。
代码实现:
#include <iostream>
using namespace std;
int PathNum(int n,int m)
{
if(n==0||m==0)
{
return 1;
}
return PathNum(n-1,m)+PathNum(n,m-1);
}
int main() {
int n,m;
cin>>n>>m;
cout<<PathNum(n,m)<<endl;
return 0;
}