加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

水题入门:关于大数阶乘

发布时间:2020-12-14 03:42:41 所属栏目:大数据 来源:网络整理
导读:最近很无聊啦,去hdu随便翻翻,做一些题来解闷。 看到1042题目,就是求大数阶乘,话说,大数的题目我还没有认真写过! 为什么?我看到大数就会用java写了~(觉得自己好颓废,总是取现成的东西……) 题目就是很简单啦, 求0到10000的阶乘 首先,我很快速地用

最近很无聊啦,去hdu随便翻翻,做一些题来解闷。

看到1042题目,就是求大数阶乘,话说,大数的题目我还没有认真写过!

为什么?我看到大数就会用java写了~(觉得自己好颓废,总是取现成的东西……)

题目就是很简单啦,求0到10000的阶乘

首先,我很快速地用c++写了一下代码,觉得没问题,就是计算10000!阶乘觉得很慢。觉得肯定会tle。但是再认真一看竟然时间限制是5000MS真是很完美。之后我就很高兴地交了上去,后来发现。RuntimerError.不够内存啊!!!!

我第一次用指针int * fact以及malloc啊,我能说我一直都用vector等吗?

竟然出错了……后来我发现我没有free(fact),后来就加上去,还是出错了。还没想明白。

突然,一贯将题目简单化的我,又开始用java写了,话说我好久没写java了,小小生疏。

果断用BigInteger水过了。贴个毫无营养的代码。话说,刷英雄会刷了一段时间,我连hdu要提交的类名是Main都忘记了.

import java.math.*;
import java.util.Scanner;

public class Main {
    public static void main(String [] args){
        int n;
        Scanner sc=new Scanner(System.in);
        while(sc.hasNextInt()){
                n=sc.nextInt();

                BigInteger i=BigInteger.valueOf(n);
                 if(n==0) i=BigInteger.ONE;
                for(int tmp=n-1;tmp>=2;tmp--){
                        i=i.multiply(BigInteger.valueOf(tmp));
                }
                System.out.println(i);
        }


    }
}

的确,从搞ACM开始,我一直就在水大数的题目,从A+B开始。哈哈。

不过我没有那么容易放弃c++,水完了之后我马上就去修改我的C++代码了,我放弃了指针数组了,直接申请了int fact[80000]。

提交,轻松过了,不过,运行时间比java长……

突然想起一个很简短的老笑话。

"咚咚咚!"
"谁?"
过了很久。
“java。”

高端黑啊。

好啦,回归正题,关于大数阶乘,我相信很多人都知道啦(除非你跟我一样水),但是我想用自己的语言来概括一下思路。

1.用数组来记载数字。

2.避免溢出,用高位去乘低位,即像求13阶乘。求到12!=479001600后,

不要这样:? ? ? ? ? ? ?479001600 ? ? ? ? ? ? ? ? ? ? ? ?应该要 ? ? ? ? ? ? ? ? ? ? ? ? ? 13? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?X ? ? ? ? ? ? ? ? 13 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? X ? ? 479001600

? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-------------------- ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ------------------------

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1437004800 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?479001600 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .

? ? ? ? ? ? ? ? ? ? ? ? ? ?------------------------ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 6227020800 ? ? ? ? ? ? ? ? ? ??

因为这样利用原来的自带的乘法,乘完之后就不会怕溢出,最多就是n+1位。

3.结果直接保存在单元中,再进行进位。

附上C++代码,注释那些是我错误的痕迹,求指正。

/*******************************************************************************/
/* OS           : 3.2.0-58-generic #88-Ubuntu SMP Tue Dec 3 UTC 2013 GNU/Linux
 * Compiler     : g++ (GCC)  4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
 * Encoding     : UTF8
 * Date         :
 * All Rights Reserved by yaolong.
 *****************************************************************************/
/* Description: ***************************************************************
 *****************************************************************************/
/* Analysis: ******************************************************************
 *****************************************************************************/
/*****************************************************************************/
//*

#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cstring>
using namespace std;
int fact[800000];
class Factorial{
public:
   static void carry(int bit[],int pos){
       int i,carray=0;

       for(i=0;i<=pos;i++){
           bit[i]+=carray;
           if(bit[i]<=9)
              carray=0;
           else if(bit[i]>9&&i<pos){
             carray=bit[i]/10;
             bit[i]=bit[i]%10;

           }else if(bit[i]>9&& i>=pos){

               while(bit[i]>9){
                  carray=bit[i]/10;
                  bit[i]=bit[i]%10;
                  i++;
                  bit[i]=carray;

               }
           }

       }


   }
   static void fac(int n){
      //  int *fact;
     int i,j,digit,pos;
     double sum=0;

     for(i=1;i<=n;i++)
        sum+=log10(i);

     digit=(int)sum+1;          //数据长度
   //  fact=(int *)malloc((digit+1)*sizeof(int));

     memset(fact,sizeof(fact) );   // 初始化数组

     fact[0]=1;                      // 设个位为1

     for(i=2;i<=n;i++){
        for(j=digit;j>=0;j--)
            if(fact[j]!=0){
               pos=j;               //记录最高位
               break;
            }
        for(j=0;j<=pos;j++)
            fact[j]*=i;
        carry(fact,pos);
     }
     for(j=digit;j>=0;j--){            //进位后的最高位
        if(fact[j]!=0){
               pos=j;
                 break;
        }
     }


     for(i=pos;i>=0;i--){

          cout<<fact[i];
     }
   //  free(fact);


   }

};
int main()

{
    int n;
    while(cin>>n){
       Factorial::fac(n);
       cout<<endl;

    }



    return 0;

}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读