zoukankan      html  css  js  c++  java
  • 【hdoj_1042】N!(大数)

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

    题目说明待求阶乘的数最大为10000,而10000!的位数为35660(这个数是上网查的),所以已经有的数据类型无法表示.


    思路:用int型数组存储n!的每一步计算结果,并且数组大小应该不小于35660这个数.每一步计算,手动模拟乘法的过程.


    首先看看乘法的过程.例如,1234 x 67,手动计算,有两种方法.

    方法一:先用7乘以1234,再用60乘以1234,然后再将两个结果相加.

    方法二:先后用67乘以4、3、2、1.

    方法二更容易用代码实现.具体看看方法二的过程,如下图(运算过程在右边)


    上述过程可以概括为:先乘当前位,再加上进位数,取余替换前位的值,取商作为新的进位数.


    C++代码如下:

    #include<iostream>
    using namespace std;
    
    int main()
    {
    	int n;
    	const int maxn = 35660 + 1;//10000!的阶乘一共有35660位
    	while(cin>>n)
    	{
    		int a[maxn];
    		memset(a,0,sizeof(a));
    		a[maxn-1] = 1;//按照从左到右的习惯,记录结果
    
    		int i,j;
    		for(i=2;i<=n;i++)//具体计算过程
    		{
    			int c = 0;
    			for(j=maxn-1;j>=0;j--)//用i乘以[1*2*...*(i-1)]的值
    			{
    				int x = a[j]*i + c;//[这三行是乘法的核心代码,和加法类似]
    				a[j] = x % 10;
    				c = x / 10;
    			}
    		}
    
    		for(i=0;i<maxn;i++)//规范输出,找到第一个非零的数的下标
    			if(a[i])
    				break;
    
    		//cout << "10000!一共有" << maxn-i << "位" << endl;
    
    		for(j=i;j<maxn;j++)//从非零的那一位(第i位)开始输出
    			cout << a[j];
    		cout << endl;
    	}
    
    	return 0;
    }
    上述代码,提交可以通过.


    小结:

    maxn (= 35660 + 1)这个数的设置会影响判题.

    开始设为1000,10000,对于较小的数的阶乘可以正确计算,但是无法记录10000!的结果,所以显示PE.

    后来改为20000显示PE.

    再改为40000显示超时,再上网查了一下10000的阶乘有35660位.

    做完题目之后,有测了一下,maxn=37000也会超时.

    所以,maxn可以设置为35660 ~ 36000(区间可以更精确一点)的一个数.

  • 相关阅读:
    NodeJs
    xml_MathML的基本知识点__这东西要自己实践最好
    嘻哈帮天通苑_poppin——张锋
    html5_canvas-记忆力卡片游戏
    baidu时光轴_使用window.scroll实现的
    my_poppin_and_me
    chrom_input_click
    Get filename from URL using Javascript
    UBB编辑器
    What is the best Java email address validation method?
  • 原文地址:https://www.cnblogs.com/tensory/p/6590752.html
Copyright © 2011-2022 走看看