JSK-217 階乘【大數】
阿新 • • 發佈:2018-12-11
階乘 n的階乘定義為n!=123*……*n 如3!=6 n!通常最後會有很多0,如5!=120 最後有一個0,現在統計n!去除末尾的0後,最後k位是多少 輸入格式: 第一行包括兩個數n,k 輸出格式: 如果n!不止k位,則輸出最後k位,如果不足k位,則將剩下的全部輸出 7!為5040,去除末尾的0為504,最後兩位為04 100%滿足1< =n< =20 1< =k< =9 樣例輸入 7 2 樣例輸出 04
問題連結:JSK-217 階乘 問題描述:(略) 問題分析: 階乘計算會越算越大,然而只需要計算最後k<=9位就好辦了,使用模除可以取出最後若干位來。 需要分析一下,末尾的0是怎麼來的。一般而言,有兩種產生末尾0的原因:一是乘以末尾為0的數,即10的倍數的數;二是含有因子2的數與含有因子5的數的乘積(10=2*5)得到的,而含有因子2的數遠多餘含有5因子數。 計算過程中,如果僅僅取最右邊k位持續計算則會造成有效數字的丟失,所以先多取一些位進行計算。最後再用模除取出最後k位。 程式說明
AC的C語言程式如下:
/* JSK-217 階乘 */ #include <stdio.h> typedef long long LL; #define BASE 10 #define MOD 1000000000000000LL int main(void) { int n, k, i; LL mod, ans; scanf("%d%d", &n, &k); mod = 1; for(i = 1; i <= k; i++) mod *= BASE; ans = 1; for(i = 2; i <= n; i++) { if(i % BASE == 0) continue; ans *= i; while(ans % BASE == 0) ans /= BASE; ans %= MOD; } and %= mod; // 輸出結果 char fmt[10]; sprintf(fmt, "%%0%dlld\n", k); printf(fmt, ans); return 0; }