• 洛谷P2388 阶乘之乘


    题目背景

    不告诉你……

    题目描述

    求出1!*2!*3!*4!*……*n!的末尾有几个零

    输入输出格式

    输入格式:

    n(n<=10^8)

    输出格式:

    有几个零

    输入输出样例

    输入样例#1: 复制
    10
    输出样例#1: 复制
    7


    首先末尾有0肯定就是乘10,10可以分解为2和5,显然2的数目多于5,于是就是统计5的数目

    然后可以转化一下,

    对于

    1
    1 2
    1 2 3
    1 2 3 4
    1 2 3 4 5
    1 2 3 4 5 6
    ……
    1 2 3 4 5 6 …… x

    我们来除一下5,发现能被5整除的项变成了:

    1
    1
    1
    1
    1
    1 2
    1 2
    1 2
    1 2
    1 2
    1 2 3
    1 2 3
    1 2 3
    1 2 3
    1 2 3
    ……
    1 2 3 4 5 …… x/5
    1 2 3 4 5 …… x/5
    1 2 3 4 5 …… x/5
    1 2 3 4 5 …… x/5
    1 2 3 4 5 …… x/5

    也就是5个
    1
    1 2
    1 2 3
    ……
    1 2 3 4 5 …… x/5

    这样就可以递归求解了

    另外,这次除5总共除掉了5+10+15+20+(n/5)*5个,可以用等差数列公式

    对于x应该是从5k+4开始的,多余的处理掉即可 时间复杂度O(logn)

     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<algorithm>
     4 #include<cstring>
     5 #define ll long long
     6 using namespace std;
     7 int n;
     8 ll work(int x){
     9     ll ret=0;
    10     for(int i=5;i<=x;i*=5){
    11         ret+=x/i;
    12     }
    13     return ret;
    14 }
    15 ll find(int x){
    16     if(x<5){
    17         return 0;
    18     }
    19     if(x<10){
    20         return (x-4);
    21     }
    22     ll ret=0;
    23     while((x+1)%5){
    24         ret+=work(x);
    25         x--;
    26     }
    27     ret+=1LL*5*(x/5)*(1+(x/5))/2;
    28     ret+=5*find(x/5);
    29     return ret;
    30 }
    31 int main()
    32 {
    33     scanf("%d",&n);
    34     printf("%lld
    ",find(n));
    35     return 0;
    36 }
  • 相关阅读:
    也用一下Windows Live Writer
    常用16种iOS视图切换动画
    iPad平板电脑程序开发基础规则(源址:http://www.cocoachina.com/bbs/simple/?t82559.html)
    NSXMLParser详解
    UIScrollView用法
    使用UIActivityIndicatorView 和多线程
    为视图加边框
    iPhone SDK开发基础之iPhone程序框架
    NSXMLParser详解(事例)
    iOS开发 小知识点
  • 原文地址:https://www.cnblogs.com/w-h-h/p/7805321.html
Copyright © 2020-2023  润新知