递归——另类加法、走方格的方案数

大家好,这里是bang_bang,今天来记录2道递归的典型题目

目录

1.另类加法

2.走方格的方案数


1.另类加法

另类加法__牛客网 (nowcoder.com)

给定两个int AB。编写一个函数返回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;
}

猜你喜欢

转载自blog.csdn.net/bang___bang_/article/details/131859598