洛谷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;
}

終於寫完了人生第一篇題解了,謝謝你們觀看!

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

相關文章
相關標籤/搜索