HDOJ 1018 Big Number

这里要用到一个公式——斯特林公式:,要求位数的话将等式两边取对数,log10(n!) = log10(2*PI*n)/2+n*log10(n/E),所以阶乘结果的位数为log10(n!) = log10(2*PI*n)/2+n*log10(n/E)+1(注意当n=1时,等式右边为0,要加1才行)。

#include <iostream>
#include <math.h>
using namespace std;
int main()
{
    int n,m;
    cin>>n;
    while (n--) {
        cin>>m;
        double pi;
        pi=acos(-1.0);
        double l;
        l= (m*log(double (m)) - m + 0.5*(log(double (2*pi*m))))/log(10.0);
        int len;
        len=(int) l+1;
        cout<<len<<endl;
    }
    return 0;
}


刚开始以为这道题就是简单地求出一个整数的阶乘,将其存在数组中,除去前导0就可以直接得出阶乘的位数,但是运行程序之后就发现,思路错了,因为题目条件n<10^7,但是求阶乘的时间复杂度过大,程序运行肯定超时,但是算是一种求大数阶乘的方法,在此贴出来留作以后参考。

#include <iostream>
#include <string.h>
using namespace std;
#define MAXN 10000000
int f[MAXN];
int main()
{
    int n,m;
    cin >>n;
    while (n--) {
        cin>>m;
        memset(f,0,sizeof(f));
        f[0]=1;
        int i,j;
        for (i=2;i<=m;i++) {<span style="white-space:pre">		</span>//求大数阶乘
            int s,c=0;
            for (j=0;j<MAXN;j++) {
                s=f[j]*i+c;
                f[j]=s%10;
                c=s/10;
            }
        }
        for (j=MAXN-1;j>=0;j--)
            if (f[j])
                break;
        cout<<j+1<<endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值