• JDOJ 1775: 求N!中0的个数


    JDOJ 1775: 求N!中0的个数

    JDOJ传送门

    Description

    求N!结果中末尾0的个数

    N! = 1 * 2 * 3 ....... N

    Input

    输入一行,N(0 < N < unsigned INT_MAX)

    Output

    输出一行,0的个数

    Sample Input

    5

    Sample Output

    1

    题解:

    (prod_{i=1}^{i=n})中末尾0的个数,其实就是在求中(prod_{i=1}^{i=n})能被几个10整除。

    因为(prod_{i=1}^{i=n})是连乘,所以想要乘出来一个10,那么当且仅当一个2和一个5相乘。

    我们随便脑补一下,都会发现,(prod_{i=1}^{i=n})中出现2的几率一定比出现5的几率大得多,也就是说,如果(prod_{i=1}^{i=n})中有(n)个2,(m)个5,那么不一定有(n)个10,但一定会有(m)个10.

    所以原题就变成了求(prod_{i=1}^{i=n})中能拆分出几个5。

    得出第一份代码:

    #include<cstdio>
    #define ll long long
    using namespace std;
    ll n,ans;
    int main()
    {
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            int j=i;
            while(j%5==0)
            {
                ans++;
                j/=5;
            }
        }
        printf("%lld",ans);
        return 0;
    }
    

    正确性可以保证,但是会TLE。

    原因是这道题的数据很大。如果这样从1跑到(N),再一个个拆分,就一定会爆时间。那么我们开始往优化算法的方面去想。我们发现,一次跑1个5总不会有1次跑很多个5省事。没错,优化暴力枚举的大多数方法都是在原暴力的基础上合并可以一次筛选出来的东西,一次性加一起。

    基于这个思想,我们发现,一个数中能拆出多少个5,其实就是能否拆出一个(5^n),所以我们只需要枚举判断能否拆出(5^n)即可。这样的运行效率会快非常多。

    代码:

    #include<cstdio>
    #include<cmath>
    #define ll long long
    using namespace std;
    ll n,ans,temp;
    int main()
    {
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            if(n/pow(5,i)==0)
                break;
            temp=n/pow(5,i);
            ans+=temp;
        }
        printf("%lld",ans);
        return 0;
    }
    
  • 相关阅读:
    常用的网站cms内容管理系统推荐
    PageAdmin网站内容管理系统出现403错误的解决方法
    使用PageAdmin网站内容管理系统做网站的好处
    网站建设步骤及常用建站系统分享
    企业网站建设如何选择建站公司
    如何采用PageAdmin自助建站系统来进行企业网站建设
    站群系统-站群软件系统推荐
    js计算之递归
    算法之插入排序
    javaScript设计模式之常用工厂模式
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11455132.html
Copyright © 2020-2023  润新知