PTA基础编程题目集-6-10 阶乘计算升级版

本题要求实现一个打印非负整数阶乘的函数。

函数接口定义

void Print_Factorial ( const int N );

其中N是用户传入的参数,其值不超过1000。如果N是非负整数,则该函数必须在一行中打印出N!的值,否则打印“Invalid input”。

裁判测试程序样例:

#include <stdio.h>

void Print_Factorial ( const int N );

int main()
{
    int N;
    
    scanf("%d", &N);
    Print_Factorial(N);
    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例:

15

输出样例:

1307674368000

代码长度限制 16 KB

时间限制 400 ms

内存限制 64 MB

题解:

int型位数控制的实现

%05d可以让输出控制为五位数,不足的高位用0补齐

1000的阶乘是2568位

写出来让人很有成就感的一题。首先尝试直接阶乘,但是即使使用longlong也会超出位数,于是想到手算乘法那样一位位的乘,但是那样好像过于复杂,假如阶乘得到的中间数有一位为9,此时乘以一个较大的数比如99时将得到一个三位数,甚至9*1000得到四位数,控制不确定位数的进位太过于复杂,于是想到以多位为一组,由于N<=1000,1000*99999<1010,只需要控制“一位”进位,因此选择以五位数为一组进行乘法运算。

void Print_Factorial ( const int N ){
    if(N<0) printf("Invalid input");
    else{
        //printf("%010d",10);
        int fac[600]={0};
        fac[0]=1;
        int x=N,k=0;
        for(int i=2;i<=N;i++){
            int temp=fac[0]*i;
            if(k || temp/100000){//结果超过五位数
                int flag=0,carry=0;//进位控制
                for(int j=0;j<=k;j++){
                    temp=fac[j]*i;
                    fac[j]=temp%100000;
                    //if(i==14)printf("fac[%d]=%d temp=%d\n",j,fac[j],temp);
                    if(flag) {//加上上次的进位
                        int fleet=fac[j]+carry;
                        fac[j]=fleet%100000;
                        carry=0;//加完carry就马上将carry复位,以免影响下一次进位
                        //if(i==14)printf("carry%d+fac[%d]=%d ",carry,j,fac[j]);
                        carry+=(fleet/100000);//进位后再次产生进位的话
                        //if(i==14)printf("@%d\n",carry);
                    }
                    if(temp/100000){//如果进位,需要在下次循环加进去
                        flag=1;
                        carry+=(temp/100000);
                        if(j==k) k++;
                        //if(i==14)printf("here carry,carry=%d,k=%d\n",carry,k);
                    }
                    else {flag=0;carry=0;}//没有进位则需要还原flag和carry
                }
            }
            else{//五位数内直接运算
                fac[0]*=i;
            }
        }
        for(int i=k;i>=0;i--){//分段输出结果
            if(i==k) printf("%d",fac[i]);
            else printf("%05d",fac[i]);
        }
        
    }
    return ;
}

以为会有数学方法简化阶乘计算,结果看了很多答案都是这样的模拟竖式的方法,并且都是逐位相乘。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值