【算法训练营】求最小公倍数+另类加法+走方格的方案数

【算法训练营】求最小公倍数+另类加法+走方格的方案数_第1张图片

7月31日

  • 求最小公倍数
    • 题目
    • 题解
    • 代码
  • 另类加法
    • 题目
    • 题解
    • 代码
  • 走方格的方案数
    • 题目
    • 题解
    • | 1 | 2 | 3 |
    • | 4 | 5 | 6 |
    • | 7 | 8 | 9 |
    • 代码

求最小公倍数

题目

【算法训练营】求最小公倍数+另类加法+走方格的方案数_第2张图片
点击跳转: 求最小公倍数

题解

最小公倍数 = 两数之积除以最大公约数,这里使用碾转相除法进行最大公约数的求解:即a与b的最大公约数可以转化为a、b之间的余数为两者之间最小的数之间的公约数。所以对于输入的两个数进行连续求余,直到余数为0,求余的分母即为结果。

代码

#include 
using namespace std;

// 计算两个数的最大公约数
int GCD(int a, int b) {
    if (b == 0)
        return a;
    return GCD(b, a % b);
}

int main() {
    int a, b;
    cin >> a >> b;

    // 求解最小公倍数
    int LCM = (a * b) / GCD(a, b);

    cout << LCM << endl;
    return 0;
}

另类加法

题目

【算法训练营】求最小公倍数+另类加法+走方格的方案数_第3张图片
点击跳转: 另类加法

题解

按位与和按位异或:
【算法训练营】求最小公倍数+另类加法+走方格的方案数_第4张图片

  • 【题目解析】
    本题的意思是自己实现加法,不适用现成的运算符,考察大家对于运算符的灵活运用
  • 【解题思路】:
    本题可以通过位运算实现,具体实现如下:
    两个数求和,其实就是 求和后当前位的数据+两个数求和的进位
    例如:
    1 + 2; 00000001 + 00000010
    求和后当前位的数据: 00000011 ; 求和后的进位数据: 没有进位,则 00000000
    两者相加,则得到: 00000011 就是3
    2 + 2; 00000010 + 00000010
    求和后当前位的数据: 00000000, 1和1进位后当前为变成0了
    求和后进位的数据: 00000100, 两个1求和后进位了
    相加后得到: 00000100 就是4
    求和后当前位的数据:简便的计算方法就是两个数进行异或 00000001 ^ 00000010 -> 00000011
    求和后进位的数据:简便的计算方法就是两个数相与后左移一位 (00000010 & 00000010) << 1
    所以这道题使用递归更加容易理解

代码

class UnusualAdd {
  public:
      int addAB(int A, int B) {
            if (A == 0) return B;
            if (B == 0) return A;
            int a = A ^ B;//求和后当前位的数据
            int b = (A & B) << 1;//求和后进位的数据
            return addAB(a, b);//递归两个数进行相加,任意为0时截止
         
    }
};

走方格的方案数

题目

链接: link【算法训练营】求最小公倍数+另类加法+走方格的方案数_第5张图片
点击跳转: 走方格的方案数

题解

本题为求取路径总数的题目,一般可以通过递归求解,对于复杂的问题,可以通过动态规划求解。此题比较简单,可以通过递归解答。
【解题思路】:
class UnusualAdd {
public:
int addAB(int A, int B) {
if (A == 0) return B;
if (B == 0) return A;
int a = A ^ B;//求和后当前位的数据
int b = (A & B) << 1;//求和后进位的数据
return addAB(a, b);//递归两个数进行相加,任意为0时截止
}
};

| 1 | 2 | 3 |

| 4 | 5 | 6 |

| 7 | 8 | 9 |

  1. 对于上面的nm(33)的格子,有两种情况
    a. 如果n或者m为1,则只有一行或者一列,从左上角走到右下角的路径数为n + m
    比如: 1 * 1格子,可以先向下走,再向右走,到达右下角;或者先向右走,
    再向下走,到达右下角,共两条,即 1 + 1 = 2,对于1 * m和 n * m的
    情况 自己画一下
    b. 如果n,m都大于1,那么走到[n][m]格子的右下角只有两条路径,
    <1>: 从[n - 1][m]格子的右下角向下走,到达
    <2>: 从[n][m - 1]格子的右下角向右走,到达
    所以走到[n][m]格子的右下角的数量为[n-1][m] + [n][m - 1],可以通过递归实现,情况a为递归的终止条件。

代码

#include
using namespace std;
int pathNum(int n, int m) {
     if (n > 1 && m > 1)
         //b情况,递归
         return pathNum(n - 1, m) + pathNum(n, m - 1);
     else if (((n >= 1) && (m == 1)) || ((n == 1) && (m >= 1)))
         // a情况,终止条件
      return n + m;
   else
         
     //格子为0时, 路径为0
         return 0;
}
int main() {
    int n, m;
     while (cin >> n >> m)
         {
      cout << pathNum(n, m) << endl;
   
    }
     return 0;
}

【算法训练营】求最小公倍数+另类加法+走方格的方案数_第6张图片

你可能感兴趣的:(算法题解,算法)