阶乘
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位。
程序说明:
????程序中,输出k位前置为0的数的做法略微与众不同,值得效仿。用循环处理来实现高位补0那是浮云。
参考链接:(略)
题记:格式字符串也是可以在程序中算出来的。
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; }