JSK-217 阶乘【大数】

阶乘
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;
}

相关文章

自1998年我国取消了福利分房的政策后,房地产市场迅速开展蓬...
文章目录获取数据查看数据结构获取数据下载数据可以直接通过...
网上商城系统MySql数据库设计
26个来源的气象数据获取代码
在进入21世纪以来,中国电信业告别了20世纪最后阶段的高速发...