hdu 1018

一道大数题目,本来想用大数运算做,考虑到数目太大 10^7,觉得应该有其他更有效的方法。


方法1:分解法:

log10(n!)=log10(1*2*3…*n)=log10(1)+log10(2)+…+log10(n)

#include<cstdio>
#include<cmath>
using namespace std;
int main(){
    long long n, k;
    scanf("%lld", &n);
    for(int i = 0; i < n; i++){
        scanf("%lld", &k);
        double len = 0;
        for(long long i = 1; i <= k; i++){
            len += log10(double(i));
        }
        printf("%lld\n", (long long)(len) + 1);
    }
    return 0;
}

方法2 :斯特林公式法

斯特林公式
当n增加时,(ln n!)与o (n ln n − n)之比趋于1。
当n增加时,(ln n!)与o (n ln n − n)之比趋于1。

维基百科链接

#include<cstdio>
#include<cmath>
using namespace std;
const double e =  2.71828182846;
const double pi = 3.1415926536;
int main(){
    long long n, k;
    scanf("%lld", &n);
    for(int i = 0; i < n; i++){
        scanf("%lld", &k);
        if(k == 1){
            printf("1\n");
        }
        else{
            long long len = log10(sqrt(2 * pi * k)) + k * log10(double(k / e));
            printf("%lld\n", len + 1);
        }
    }
    return 0;
}

用斯特林公式有一点要考虑到,不能直接应用公式,而要将公式变形,否则处理特大数的时候会发生错误。

参考自这篇博客

猜你喜欢

转载自blog.csdn.net/qq_40721694/article/details/82262528
今日推荐