求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;
}