1. 程式人生 > >【USACO習題】階乘問題

【USACO習題】階乘問題

aps 一位 alt splay n) isp amp pan opened

本題在洛谷上的鏈接:https://www.luogu.org/problemnew/show/P1134


剛開始做的時候,是這樣想的,只有n個數的最後一位才會對答案造成影響,所以只管最後一位就好,但是還要把某位多余的0除掉。結果只對了兩個點,我們只保留最後一位導致運算出現了誤差,比如n=15時就會出錯,解決辦法是每次適當多保留幾位,但比較糊弄。。。

還有一種辦法是求出2和5的個數,因為2的個數一定不少於5的個數,且一對2和5相乘會在末尾產生一個0,所以用2的個數減5的個數,剩下的就是實際會對答案造成影響的2的個數。

另外,有一種看起來很高端的做法,可以證明每次乘8或乘5對末位的影響是一樣的,所以可以將乘5換成乘8,而乘8每4次末位一循環。這樣做,實際上每次遞歸求解(n/5)!的末位,再與之前的相乘,也可以通過叠代實現。

技術分享圖片
 1 #include <cstdio>
 2 
 3 const int a[4] = {6, 8, 4, 2};
 4 
 5 int main() {
 6     int n, ans = 1;
 7     scanf("%d", &n);
 8     while (n > 0) {
 9         for (int i = 1; i <= n % 10; ++i)
10             if (i != 5) ans = ans * i % 10;
11         n /= 5;
12         ans = ans * a[n % 4
] % 10; 13 } 14 printf("%d", ans); 15 return 0; 16 }
AC代碼

【USACO習題】階乘問題