求10000以内n的阶乘(链表实现)

求10000以内n的阶乘

 5000ms  655360K

描述:

求10000以内n的阶乘。

输入:

只有一行输入,整数n(0<=n<=10000)。

输出:

一行,即n!的值。

样例输入:

100

样例输出:

93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

我们创建一个双向链表(方便后续的倒序输出),链表的每个节点存储五位数,

第一个节点值赋1,然后进行循环反复乘i即可得到n!

同时,每次循环进行时还需要对进位进行处理,当存在进位或者还有需要处理进位的节点时循环

当有进位但下一个节点不存在时创建新的节点保存进位,因此,最终得到的链表是倒序存储的

处理完所有进位之后得到n!便可以倒序输出,同时要注意除了最高位所在节点之外,其他值为0的节点都需要补齐五位0

#include <stdio.h>
#include <stdlib.h>
typedef struct node //双向链表,方便倒序输出
{
    int a;
    struct node *next;
    struct node *pre;
} node;
typedef node* pnode;//节点的指针
int main()
{
    pnode head,p,q,last;
    head=(node*)malloc(sizeof(node));
    head->a=1;
    head->next=NULL;
    head->pre=NULL; //head的初始化
    last=head;//防止阶乘值较小时尾结点是首节点,last为野指针
    int n,i;
    int tmp;
    scanf("%d",&n);
    if(n==0)
    {
        printf("1");
        return 0;
    }
    for(i=1; i<=n; ++i)
    {
        p=head;
        while(p) //循环做每个节点值*i即可得到n!
        {
            p->a=i*(p->a);
            p=p->next;
        }
        p=head;
        tmp=0;
        do//处理进位,
        //do while防止由于第一个节点的next域为null,导致数据一直停留在第一个节点内
        {
            tmp+=p->a;
            p->a=tmp%100000;//每个节点节点只保留五位,其余用于进位
            tmp=tmp/100000;
            if(!(p->next)&&tmp)//如果还有进位而且p指向尾结点
            {
                q=(pnode)malloc(sizeof(node));
                q->next=NULL;
                q->a=0;
                q->pre=p; //尾插链接到链表
                p->next=q;
                last=q;//记录尾结点位置
            }
            p=p->next;
        }while(tmp||p);//仍有进位,或者仍有节点值需要判断进位时继续循环
    }
    p=last;
    printf("%d",p->a);//最高位不需要补0,单独输出
    last=last->pre;
    free(p);
    p=last;
    while(p)//倒序输出
    {
        //除最大位的节点外都要补0,保证是五位
        printf("%05d",p->a);
        last=last->pre;
        free(p);
        p=last;
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

OrientalGlass

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值