【USACO习题】阶乘问题
本题在洛谷上的链接: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 }