继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

大数——大数阶乘(hdu1042)

九日王朝
关注TA
已关注
手记 180
粉丝 41
获赞 185

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1042



题目描述:题目异常的简洁,所以很容易入坑。其实想一想,10000!这个数确实蛮恐怖的~

一、我们设一个递减的整数为n,存放值的字符串为s。每次s内的所有字符都将与n做一次相乘操作,

即循环体内:

                                s[j]=s[j]*i+k;             //k为进位
k=s[j]/10; 
s[j]%=10;                

那么这个循环究竟循环多少次呢?很明显,是s的有效长度。

那么s的有效长度又是多少呢?

s的值越来越大,长度也是不断的增长。如果我们一开始就将s设置为0000000000000……00000000000000000001

那么会产生无数次无效的运算操作,很显然不是很合理。

所以我们设置一个记录s长度的变量来控制循环的次数,我们假设为t。

n的上限为10000,所以s一次乘操作他的值最大变化为后面加4个0,也就是单次处理  t最多加4。

一个看起来不是很正规但是很简单的处理:if(s[t-3]||s[t-2]||s[t-1]||s[t])    t+=4;   如果s后四位不全是0,那么意味着下次乘操作可能会溢出。

所以再给t补充4位


二、考虑0和1的输入



#include<stdio.h>#include<string.h>int main(){	int n,i,j,t,k;	int s[50001];	while(~scanf("%d",&n))	{		memset(s,0,sizeof(s));		if(n==0||n==1)		printf("1\n");else{		s[0]=1;		k=0;		t=4;		for(i=n;i>=2;i--)		{			for(j=0;j<=t;j++)			{					s[j]=s[j]*i+k;				k=s[j]/10;				s[j]%=10;			}		if(s[t-3]||s[t-2]||s[t-1]||s[t])		t+=4;	}		while(!s[t])		t--;for(i=t;i>=0;i--)printf("%d",s[i]);printf("\n");		}	}	return 0;}







    

思路2:加法运算是从个位(末端)开始,并且涉及到进位。


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP