算法学习10146(计算阶乘的位数)
来源:互联网 发布:知乎 放假 编辑:程序博客网 时间:2024/06/04 18:21
Number Length
Problem descriptionN! (N factorial) can be quite irritating and difficult to compute for large values of N. So instead of calculating N!, I want to know how many digits are in it. (Remember that N! = N * (N - 1) * (N - 2) * ... * 2 * 1)InputEach line of the input will have a single integer N on it 0 < N < 1000000 (1 million). Input is terminated by end of file.
OutputFor each value of N, print out how many digits are in N!.
Sample Input
13320001000000Sample Output
1 11302715565709
看到求阶乘的题目,第一反应就是用递归了,可是注意到这里的输入范围是1~1000000,而在32位系统中(现在基本上int都是32位),范围-2147483648~+2147483647。unsigned类型 的int 范
围:0~4294967295 即 0~(2的32次方-1),所以用递归把阶乘结果计算出来以后再算位数是会越界的,除非用数组保存阶乘结果,但感觉略麻烦。这里我用了3种方法来计算阶乘的位数:
方法一:直接利用公式计算阶乘结果以及位数:对于数n求位数:log10(n)+1即可,只要注意的是,<math.h>中log10(n)的返回值是double,所以要转换成int。
int main()
{double pi = acos(-1);int n;double temp;int result;while(scanf("%d",&n)&&n!=EOF){temp=n*log(n)-n+0.5*log(2*n*pi);result=(int)(temp/log(10))+1;printf("%d\n",result);}return 0;}
方法二:利用迭代,原本计算公式应该是(n*(n-1)*...*2*1)/(10*10*...*10),计算能除多少个10,结果再加1.现在是从第一个n开始就除10,判断能否除完以后的结果>1,如果大于1,就result++,
把结果继续乘(n-1),再除10,同样计算;如果不能除10,就乘以(n-1)后再判断。
int main(){int n ;while(scanf("%d",&n)!=EOF){int result=1;int i;double temp = 1;for(i=n;i>0;i--){temp*=i;while((temp/10)>1){result++;temp=temp/10;}}printf("%d\n",result);}return 0;}方法三:使用动态规划的思想,提高速率。将1000000个结果都先保存在result[1000000]数组中,根据log10(n*(n-1)*(n-2)*...*2*1)=log10(n)+log10(n-1)+...+log10(2)+log10(1)的公式,
直接计算出阶乘的位数,所以result[n] = result[n-1]+log10(n);
double result[1000000];//全局变量
void add(int n)
{
if(n==1) result[1]=log10(1); else result[n]=result[n-1]+log10(n);}int main(){ int n; int length=0; int i; double temp; for(i=1;i<=1000000;i++) add(i); while(scanf("%d",&n)!=EOF) { length = 1+(int)result[n]; printf("%d\n",length); } return 0;}其实一开始这三种方法怎么试都通不过学校ACM的测试器,一直报超时,困惑了很久,发现原来是死在了输入上!
原先所有方法的循环输入我是这么写的:
while(scanf("%d",&n)&&n!=EOF)
但是正确的输入应该是:
while(scanf("%d",&n)!=EOF)
错误出现在哪里使他死循环了呢?
当读到输入文件的末尾,scanf会返回EOF。scanf要么返回1(成功匹配input),要么返回-1(读到文件末尾),EOF在C的头文件里面是一个宏,
通常的值为-1,但是如果写成n!=EOF,我输入的n的确是永远都不会是-1的,因为输入在1~1000000,也就是当我到达输入文件的末尾时,&&的左右
两项都不会为0,while()内的条件永真,死循环---->超时!
0 0
- 算法学习10146(计算阶乘的位数)
- 阶乘位数的计算
- 计算阶乘的位数 poj 1423
- POJ 1423 计算阶乘的位数
- 计算一个数阶乘的位数
- 阶乘位数计算
- 【算法王道】n阶乘的位数
- NEFU OJ26 计算阶乘位数
- nefu 26 计算阶乘位数
- 菜鸟的大数阶乘的位数公式计算
- POJ 1423 Big Number 大数阶乘的位数计算
- hdu(1018)Big Number(阶乘位数的计算)
- hdu 1018 计算一个数阶乘的位数
- HDU--1018--Big number!(计算阶乘结果的位数)
- 阶乘的位数
- 阶乘的位数
- 求阶乘的位数
- 大数阶乘的位数
- Android之Vibrator使用。
- 自动更新系统(二)
- 关于MAX485用法
- Shape 的简单使用
- iReport 4.1 报表制作,子报表,实例解析
- 算法学习10146(计算阶乘的位数)
- 简要介绍央行现有的几个支付系统
- 菜单组轮播
- jquery实现的ajax多图上传(移动端)
- 神奇的angularJS——简单的angular例子
- 《Hadoop基础教程》之初识Hadoop
- Android,已知应用名称, 通过应用名称来启动应用
- 忘川
- stm32硬件错误的排除方法