• PE5 Smallest multiple


    题目

    2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.

    What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?

    https://projecteuler.net/problem=5

    分析

     

    可以将题目理解为求1-20的最小公倍数,即设计一个求多个数的最小公倍数函数。我将函数原型设为:__int64 Arr_Lcm(vector<int> v);

    解法1(公倍数法):利用求两个最小公倍数方法:int Lcm(int a, int b);先求出其中两个数的最小公倍数,再求这个最小公倍数与第三个数的最小公倍数,依次求解

    解法2(素数法):可以观察到:LCM1~10=    2 ^ 3 * 3 ^ 2 * 5 ^ 1 * 7 ^ 1 = 2520

                                1.列出20以内的质数,并求这些质数的小于20的最高次幂

    2.再将这些质数的最高次幂的积相乘

    ps:这个方法也是PE官网Download overview给出的方法,分析写了好长(看了半天没看懂),

    后来结果看到@cfeibiao博客的这句话,秒懂了,就不贴这个方法的代码了,可以参考他博客中Python的实现。

    Code

     

    Lcm利用了求最大公约数(Gcd)的方法,和结论(两数之积 = Lcm*Gcd)此外还要注意返回时要用大于__int64,使用int,会发生了上溢,得到错误结果;

    代码部分,顺便把Arr_Gcd的方法也写了,把最大公约数,最小公倍数 的方法给总结了。

     

    #include <iostream>
    #include <vector>
    
    using namespace std;
    int Lcm(int a, int b);
    __int64 Arr_Lcm(vector<int> v);
    int Gcd(int a, int b);
    int Arr_Gcd(vector<int> v);
    int main(){
    
        vector<int> v = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
        __int64 r = Arr_Lcm(v);
        cout << r;
        return 0;
    }
    int Gcd(int a, int b){
        if (a < b)swap(a, b);
    
        while (b != 0)
        {
            int tmp = a % b;
            a = b;
            b = tmp;
        }
        return a;
    }
    int Lcm(int a, int b){
        int f = Gcd(a, b);
        return (__int64)a*b / Gcd(a, b);
    }
    __int64 Arr_Lcm(vector<int> v){
        __int64 a = v[0];
        __int64 b;
        for (int i = 1; i < v.size(); i++)
        {
            if (i == 18){
                int f = 1;
            }
            int tt = v[i];
            b = Lcm(a, v[i]);
            a = b;
        }
        return a;
    }
    int Arr_Gcd(vector<int> v){
        int a = v[0];
        int b;
        for (int i = 0; i < v.size(); i++)
        {
            b = Gcd(a, v[i]);
            a = b;
        }
        return a;
    }

     

     

    Mathematica  

    LCM @@ Range[1, 20]

    by the way C++的vector好像没有vector初始化为递增序列的,利用Mma、Range[1,20]粘贴复制真是爽,除此之外还可以做各种验证、计算来辅助分析!

    用vs断点增删代码来测试数据,点F5实在麻烦。

    Mma简直就是个超级计算器,没用过的同学,上面一行简洁的代码有没有打动你~~....!。

     

    参考:cfeibiao

     

  • 相关阅读:
    TCP和UDP的一些区别: TCP提供可靠传输的机制:
    rpc和 http的区别
    熔断原理与实现Golang版
    源码解读 Golang 的 sync.Map 实现原理
    mysql底层为啥用b 树不用红黑树_MySQL索引底层数据结构
    一条sql 查询语句是如何执行的
    网络相关知识
    为什么遍历 Go map 是无序的?
    Go语言 参数传递究竟是值传递还是引用传递的问题分析
    解决goland debug 调试问题 Version of Delve is too old for this version of Go
  • 原文地址:https://www.cnblogs.com/dingblog/p/4502200.html
Copyright © 2020-2023  润新知