洛谷P2388—阶乘之乘题解

不会用高精作的蒟蒻献上本身的第一篇题解(第一次写,写的很差你们多多包涵)ios

根本就不用高精的啊喂!优化

数学解法spa

https://www.luogu.com.cn/problem/P2388code

正题开始blog


要求n个阶乘的积,就要先将其中一个数阶乘的乘积求出来。ci

那么一个数阶乘乘积后0的个数要怎么求呢?get

有话快说数学

直接求这个阶乘里有多少个质因数5就行!it

???io

众所周知正整数相乘末尾是0的只能是2的倍数与5的倍数相乘,2的倍数铁定是比5的倍数要多的那么咱们就能够一项一项求了!

暴力代码以下:

#include<iostream>
using namespace std;
int hhh(long long a)
{
    int sum=0;
    while(a%5==0)//不能用if,由于要求这里面有多少个质因数5,有的数不止一个,好比25
        sum++,a/=5;
    return sum;
}
int main()
{
    long long i,n,ans=0,j;//不开long long见祖宗
    cin>>n;
    for(i=1;i<=n;i++)
        for(j=1;j<=i;j++)
            ans+=hhh(j);//计算当前数有几个质因数5
    cout<<ans;
    return 0;
}

一看就会TLE啊

怎么优化呢?

不要急,且听我慢慢道来

有话快说!

先将1~n的阶乘拆成两部分:

1!=1   2!=2*1!   3!=3*2!……n!=n*(n-1)!

第二部分是咱们上一步算的,因此要求n!后有几个0,只用求n*2^y后0的个数(其实就是求n有几个质因数5)+上一步计算的(n-1)!后0的个数(就是求一、二、3……n-1里有几个质因数5)

改良后的代码以下:

#include<iostream>
using namespace std;
long long sum=0;//不开long long……我是否是已经说过了?
void hhh(long long a)
{//不要初始化,要记忆化(迫真
    while(a%5==0)
        sum++,a/=5;
}
int main()
{
    long long i,n,ans=0;
    cin>>n;
    for(i=1;i<=n;i++)
        hhh(i),ans+=sum;
    cout<<ans;
    return 0;
}

终于写完了人生第一篇题解了,谢谢你们观看!

完结撒花(。・∀・)ノ🌹

相关文章
相关标签/搜索