zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    HDU 4452 模拟
    CSUFT2016ACM训练赛4
    HDU 4445 纯物理题+枚举
    HDU 4442 排队贪心
    2016中国大学生程序设计竞赛
    POJ 2239 化二分图右集合二维为一位的最大匹配
    学习数据库必须掌握的54条SQL查询语句
    jsp+连接MYSQL5.1
    查看MYSQL 端口
    J2EE+struts2+helloworld调试问题解决方法
  • 原文地址:https://www.cnblogs.com/dingblog/p/4502200.html
Copyright © 2011-2022 走看看