51Nod-1057-N的阶乘

输入N求N的阶乘的准确值。
Input
输入N(1 <= N <= 10000)
Output
输出N的阶乘
Input示例
5
Output示例
120

遇见这道题,也是我的运气,因为以前根本没有想过这种高精度的题还可以这样子做,太神奇了,先发一下我原来的做法。

#include <stdio.h>
#include <string.h>
#define _MAX 6
#define MAX_ 10000000
int product[MAX_];
int pro[MAX_], num[_MAX];
int rank = 1;

//递归进位函数
void Carrying(int tag,int i,int j,int *p)
{
    p[i+j]+=tag;
    if (i + j + 1 > rank || (i + j + 1 == rank && p[i + j] > 9))
    {
        rank++;
    }
    if (p[i+j]>9)
    {
        tag=p[i+j]/10;
        p[i+j] %=10;
        Carrying(tag, i+1, j, p);                                //写成Carrying(tag, i, j+1, p);也成立,为了让i+j递增而已
    }
    return ;
}

//乘法
void multiplication(int N)
{
    int i=0,j=0,numLen,productLen,tag;
    for (i = 0; N > 0; i++)
    {
        num[i] = N % 10;
        N /= 10;
    }
    numLen = i;
    productLen = rank;
    for (i = 0; i < productLen; i++)
    {
        pro[i] = product[i];
    }
    memset(product, 0, sizeof(int) * MAX_);

    //逐位相乘
    for (i=0; i<productLen; i++)
    {
        for (j=0; j<numLen; j++)
        {
            tag= pro[i] *  num[j];
            Carrying(tag, i, j, product);                          //递归
        }
    }
    return ;
}

int main()
{
    int N, i = 2, j;
    scanf("%d", &N);
    memset(product, 0, sizeof(int) * MAX_);                    //初始化product数据为0
    product[0] = 1;
    for (; i <= N; i++)
    {
        multiplication(i);
    }
    //倒序输出结果
    for (j = rank - 1; j >= 0; j--)
    {
        printf("%d",product[j]);
    }
    printf("\n");
}

这种做法比较细碎,所以在这道题的测试数据下,只过了五分之二的测试数据,剩下的悉数超时,所以,我不得不寻求其他更简单的方法,于是乎,就遇见了下面这个巧妙的方法。

#include <stdio.h>
#define _MAX 100000000
int main()
{
    int n, i, j, m;
    long long a[10000], c;
    scanf("%d",&n);

    m = 0;
    a[0] = 1;
    for(i = 1; i <= n; i++)
    {
        c = 0;
        for(j = 0; j <= m; j++)
        {
            a[j] = a[j] * i + c;
            c = a[j] / _MAX;
            a[j] %= _MAX;
        }
        if(c > 0)
        {
            m++;
            a[m] = c;
        }
    }
    printf("%lld", a[m]);
    for(i = m - 1; i >= 0; i--)
        printf("%0.8lld", a[i]);
    printf("\n");
    return 0;
}

这里我们知道,如果简单的用乘法去阶乘,那么不用多大,立马就爆了数据范围,于是,这道题的这个解法巧妙的对这个超级大的数进行了切分,具体切成多宽的看个人爱好,只要能够用几个数据类型装下来就好,这里我们划分成了8个的宽度,每八位存一下,最后再进行格式化输出,巧妙的避开了爆数据范围的问题。看着代码理解起来并不难,提示一下,c和进位相关,m和切的段数相关,就这样,相信大家看看都是可以理解的,如果无法理解,那么只能说,回去学学数学吧,乖Y(^_^)Y!!!

全部评论

相关推荐

双飞二本嵌入式求拷打我是在&nbsp;BOSS&nbsp;上投递的简历,好多都没人回复,这是开场白和简历求大神帮忙看看。您好!我是2025届应届生,最快可在一周内上岗,能够实习六个月以上,并接受加班。以下是我的核心优势和相关经验:1.&nbsp;嵌入式开发能力:&nbsp;&nbsp;&nbsp;熟练掌握STM32系列单片机及其外设(如GPIO、定时器、ADC、DAC、I2C、SPI、UART等),能够独立完成硬件驱动开发和调试。&nbsp;&nbsp;熟悉FreeRTOS实时操作系统,具备多任务调度和资源管理经验。&nbsp;&nbsp;熟悉LVGL图形库开发,能够实现嵌入式设备的图形界面设计。2.&nbsp;硬件设计能力:&nbsp;&nbsp;&nbsp;具备PCB设计经验,曾为2023年工创赛物流搬运赛道设计小车主板,带领团队获得国家级银奖。&nbsp;&nbsp;&nbsp;熟悉硬件原理图分析,能够快速理解并调试硬件电路。3.&nbsp;机器人开发与竞赛经验:&nbsp;&nbsp;&nbsp;在全国大学生智能车竞赛、ROS机器人竞赛中多次获得国家级奖项,具备丰富的机器人开发经验。&nbsp;&nbsp;&nbsp;熟悉Linux环境,对ROS和ROS&nbsp;2有一定了解,能够进行机器人系统的开发与调试。4.&nbsp;编程能力:&nbsp;&nbsp;&nbsp;熟悉C/C++,熟悉Python,能够高效完成嵌入式开发和算法实现。&nbsp;&nbsp;&nbsp;具备良好的代码规范和文档编写能力。5.&nbsp;团队协作与领导能力:&nbsp;&nbsp;&nbsp;在多个项目中担任核心开发或团队负责人,具备良好的沟通能力和团队协作精神。&nbsp;&nbsp;&nbsp;在工创赛中带领团队完成项目规划、任务分配和技术攻关,展现了较强的领导力。我对嵌入式开发、机器人技术和智能硬件充满热情,期待加入贵公司,与团队共同成长,为公司创造价值!如果有合适的岗位,欢迎随时联系我,期待进一步沟通!
沉淀一会:嵌入式就是狗屎
点赞 评论 收藏
分享
26牛牛不会梦到感谢信:羡慕离职了还能吃吗现在就赶回去
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务