1. 程式人生 > >靈光一現,程式碼實現

靈光一現,程式碼實現

題目 

用高精度計算出S=1!+2!+3!+…+n!(n≤10000)

其中“!”表示階乘,例如:5!=5*4*3*2*1。

開始yy

看到題目是否一下子想到直接寫兩個高精模擬一遍,太naive了

用jiao想一想都知道時間肯定過不去的啊

這時候就要走一些旁門左道

觀察式子,1!+2!+3!+4!……n!,n!=(n-1)!*n

然後把式子從左到右會發現可以Sn=((( n+1)*(n-1))*(n-2))*……*1

可以用for(i:n-1) ans=(ans+1)*i表示

現在再看耗時的差別,加法由高精加變為整數加法明顯簡單了不少

乘法由高精乘高精變為高精乘整數,迴圈次數也少了

#include<cstdio>
using namespace std;
const int mod=1e8;
int n,base=4,l=1;
long long ans[10];
void mult(){
    for(int i=0;i<l;i++)
        ans[i]*=n;
    for(int i=0;i<l;i++){
        ans[i+1]+=ans[i]/mod;
        ans[i]=ans[i]%mod;
    }
    if(ans[l]) ++l;
}
int main(){
    scanf("%d
",&n); ans[0]=0; while(n){ ++ans[0];mult();--n; } printf("%lld",ans[--l]); while(l--) printf("%08lld",ans[l]); return 0; }

 這個膜1e8屬於進位制優化,簡單的解釋為陣列的每一個單元存一個長度為8的子串

例如123456789在陣列中的情況為a[0]=2345678,a[1]=1