大数运算:HDU-1042-N!(附N!位数的计算)

解题心得:

  1. 这里使用了10000进制。很明显,因为是n!所以单个最大的数是10000*10000,使用万进制。
  2. 可以借鉴高精度的加法,单个乘了之后在进位。
  3. 很坑的一点,0!=1,数学不好WA了三次,尴尬。
  4. 10000!有35660位数,求解方法如下
    方法一:
    可以将n!表示成10的次幂,即n!=10^M(10的M次方)则不小于M的最小整数就是 n!的位数,对该式两边取对数,有 M =log10^n!
    即:
    M = log10^1+log10^2+log10^3…+log10^n
    循环求和,就能算得M值,该M是n!的精确位数。

    方法二:
    利用斯特林(Stirling)公式的进行求解。下面是推导得到的公式:
    res=(long)( (log10(sqrt(4.0*acos(0.0)n)) + n(log10(n)-log10(exp(1.0)))) + 1 );
    当n=1的时候,上面的公式不适用,所以要单独处理n=1的情况 !
    有关斯特林(Stirling)公式及其相关推导,这里就不进行详细描述,
    这种方法速度很快就可以得到结果。

题目:

                            N!

Problem Description
Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!

Input
One N in one line, process to the end of file.

Output
For each N, output N! in one line.

Sample Input
1
2
3

Sample Output
1
2
6

Author
JGShining(极光炫影)

#include<iostream>
#include<cstring>
#include<stdio.h>
using namespace std;
const int maxsize = 35660;//10000!有35660位
const int big_radix = 10000;//使用的是万进制
int num[maxsize+1];

void big_g(int n1)
{
    int carry = 0;
    int temp;
    for(int i=0;i<maxsize;i++)//核心
    {
        temp = num[i] * n1 + carry;
        num[i] = temp % big_radix;
        carry = temp / big_radix;
    }
}

void bit_prin()
{
    bool flag = false;//用于判断第一个是否为零,是零则跳过
    for(int i=maxsize;i>=0;i--)
    {
        if(flag)
        {
            printf("%04d",num[i]);
        }
        else if(num[i] > 0)
        {
            flag = true;
            printf("%d",num[i]);
        }
    }
    if(!flag)//全是零打印0
        printf("0");
    printf("
");
    return ;
}
int main()
{
    int n;
    while(cin>>n)
    {
        memset(num,0,sizeof(num));//全换位零方便之后的判断
        num[0] = 1;//初始化第一个,0!=1;
        for(int i=2;i<=n;i++)
        {
            big_g(i);
        }
        bit_prin();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/GoldenFingers/p/9107376.html