为了账号安全,请及时绑定邮箱和手机立即绑定

大数——大数阶乘(hdu1042)

标签:
算法

题目链接:

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:加法运算是从个位(末端)开始,并且涉及到进位。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消