• 2 3 5 7的倍数


    题目五、2 3 5 7的倍数

    给出一个数N,求1至N中,有多少个数不是2 3 5 7的倍数。 例如N = 10,只有1不是2 3 5 7的倍数。

    Input

    输入1个数N(1 <= N <= 10^18)。

    Output

    输出不是2 3 5 7的倍数的数共有多少。

    输入示例

    10

    10000

    1234567890

    98765

    11111111111111111

    输出示例

    1

    2285

    282186946

    22575

    2539682539682540

    解题思路:

    先说我看到这题的思路,枚举1N的所有整数用一个if判断i%2||i%3||i%5||i%7,如果为真,则ans计数器加一,时间复杂度O(n),

    1 <= N <=10^18的情况下直接GG吧。

    于是我就联想到在素数打表中的欧拉筛法,可以这么想,将1N的所有数以十为单位分组,第二个第四个第五个第六个第八个第十个数不用判断,就只需要判断每一组中,第一个元素,第三个元素,第七个元素,第九个元素是不是37的倍数。这个时间复杂度略低于第一个,遇到大树还是直接GG了。

    第三个方法我就换了个思路,同余定理,具体的理论百度就好了。在本题中,在1N中不是2 3 5 7的倍数的数 

    = N - N中是2的倍数的个数 

     - N中是3的倍数的个数 

     - N中是5的倍数的个数 

     - N中是7的倍数的个数

     +N中是23的倍数的个数

     +N中是25的倍数的个数

     +N中是27的倍数的个数

     +N中是35的倍数的个数

     +N中是37的倍数的个数

     +N中是57的倍数的个数

     -N中是2,3,5的倍数的个数

     -N中是2,3,7的倍数的个数

     -N中是2,5,7的倍数的个数

     -N中是3,5,57的倍数的个数

     +N中是2,3,5,7的倍数的个数;

    时间复杂度从O(n)降到了O(1),代码就是几个除法运算的加减就能算出结果,注意这里的N要以long long存储。

    代码:

    #include <cstdio>
    int main() {
        long long n;
        long long count = 0;
        scanf("%lld", &n);
        count = n - n / 2                 - n / 3             - n / 5             - n / 7 
                  + n / (2 * 3)         + n / (2 * 5)         + n / (2 * 7)         + n / (3 * 5)         + n / (3 * 7)         + n / (5 * 7)
                  - n / (2 * 3 * 5 )    - n / (2 * 5 * 7)     - n / (2 * 3 * 7)     - n / (3 * 5 * 7)
                  + n / (2 * 3 * 5 * 7);
        printf("%lld", count);
        return 0;
    }
  • 相关阅读:
    C#:如何设置MDI窗体
    asp.net在类库中使用EF 6.0时的相关配置
    asp.net中使用jquery ajax保存富文本的问题
    Asp.net Api中使用OAuth2.0实现“客户端验证”
    NLog在asp.net中的使用
    元素的隐藏特性
    jQuery 使用笔记
    获取标签的所有选择器存放在一个数组
    自己绘制的flex布局思维导图
    js打印三角形
  • 原文地址:https://www.cnblogs.com/MATLABlearning001/p/5396961.html
Copyright © 2020-2023  润新知