• 牛客小白月赛5-D-阶乘(求n内每个数的阶乘相乘后尾数为0的个数)


    题目描述

    输入描述:

    输入数据共一行,一个正整数n,意义如“问题描述”。

    输出描述:

    输出一行描述答案:
    一个正整数k,表示S的末尾有k个0
    示例1

    输入

    10

    输出

    7

    说明

    解题思路:求1~n每个数的阶乘相乘后尾数为0的个数。
    AC代码一(365ms):暴力枚举1~n也能过?说明测试数据不大。采用法一可以过:直接统计每个元素包含因子为5的个数。但采用法二会TLE,原因同样是暴力枚举,但每次需要重新计算当前i的因子为5的个数,而法一让很多数可以省去这一步,只当枚举到i为5的倍数才会进入那个while循环,可能超时的原因就出在这里。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 int main(){
     5     int n,num,tmp;LL sum;
     6     while(~scanf("%d",&n)){
     7         sum=0,num=0;//num一开始置0,以后每次累加每个元素包含因子为5的个数即可
     8         for(int i=1;i<=n;++i){//从1枚举到n
     9             tmp=i;//表示当前i!=(i-1)!*i
    10             while(tmp%5==0)num++,tmp/=5;//num累加当前i元素包含因子为5的个数
    11             sum+=num;//累加i!尾数为0的个数
    12         }
    13         printf("%lld
    ",sum);
    14     }
    15     return 0;
    16 }

    AC代码二(78ms):根据法一:求N!尾数有多少个0只需求N内为5的倍数的数包含因子为5的个数总和即可,而此题是求1~n内每个数的阶乘相乘之后尾数为0的个数,因此我们同样枚举N内所有为5的倍数i,每求出i包含因子为5的个数num后,因为i~n(n-i+1个元素)内每个数的阶乘都包含当前i这个元素,所以sum累加num*(n-i+1)即可。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 int main(){
     5     LL n,tmp,num,sum;
     6     while(~scanf("%lld",&n)){
     7         sum=0;
     8         for(LL i=5;i<=n;i+=5){
     9             tmp=i;num=0;
    10             while(tmp%5==0)num++,tmp/=5;
    11             sum+=num*(n-i+1);
    12         }
    13         printf("%lld
    ",sum);
    14     }
    15     return 0;
    16 }

    AC代码三(5ms):如果测试数据真的很大为10^9,那么前两个肯定是超时的。因此能否根据法二同样用O(log5n)的时间复杂度计算出尾数为0的个数?根据法二公式:假设我们要计算1!~126!,即n=126,则①126/5=25,说明126!中有25个数是5的倍数;②126/25=5,说明126!中有5个数是25的倍数;③126/125=1,说明126!中有1个数是125的倍数。现对1!~126!按包含因子为5的个数(个数相同为同一组)从小到大分成k=n/i=126/5=25组:(共有k-1组每一组有都有5i(i=1,2,3...)个数的阶乘包含因子为5的个数是相同的,最后一组有(1+n%i)个元素)

    j=1--->{5!,6!,7!,8!,9!};//有i=5个元素每个元素包含1个因子5

    j=2--->{10!,11!,12!,13!,14!};//有i=5个元素每个元素包含2个因子5

    ...

    j=24-->{120!,121!,122!,123!,124!};//有i=5个元素每个元素包含24个因子5

    j=25-->{125!,126!}//有2(1+n%i=1+126%5=1+1=2)个元素每个元素包含25个因子5

    以上分组是i=5的情况,其他i值基本和这个一样:由等差数列求和公式可求得1!*...*126!中一共有x=(1+k-1)(k-1)/2*i+k*(1+n%i)(其中k=n/i,i=51,52,53...)个因子5,之后按此公式累加(因子为5的个数)x的值(sum+=x)即可求出1!*...*n!尾数为0的个数sum。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 int main(){
     5     LL n,sum;
     6     while(~scanf("%lld",&n)){
     7         sum=0;
     8         for(LL i=5;i<=n;i*=5){
     9             LL k=n/i;
    10             sum+=k*(k-1)/2*i+k*(1+n%i);
    11         }
    12         printf("%lld
    ",sum);
    13     }
    14     return 0;
    15 }
  • 相关阅读:
    nightwatchjs --Expect element to not include text
    Iterating elements using NightWatchJS
    nightwatch 切换窗口
    nodejs读取配置文件
    spring 事务
    重载,重写,重构
    python 元组不变 列表可变
    WebStorm ES6 语法支持设置
    docker日志
    curl -O 下载文件
  • 原文地址:https://www.cnblogs.com/acgoto/p/9466590.html
Copyright © 2020-2023  润新知