Euler 160:找到阶乘的非平凡5位数

时间:2012-02-17 18:55:59

标签: c algorithm math

  

给定一个数字,在尾随0. 9之前找到5位数! = 362880   所以f(9)= 36288 10! = 3628800所以f(10)= 36288 20! = 2432902008176640000   所以f(20)= 17664求f(1,000,000,000,000)

为此,我计算了f(10^6)然后f(10^12) = (f(10^6))^(10^6)来计算f(n) ...我正在计算 通过删除任何5和相应的2所以所有的因子 尾随零被删除。
但我得到了错误的答案 方法有问题或有些愚蠢的错误吗?

参考代码

long long po(long long n, long long m, long long mod) {
    if (m == 0) return 1;
    if (m == 1) return n % mod;
    long long r = po(n, m / 2, mod) % mod;
    if (m % 2 == 0) return (r * r) % mod;
    return (((r * r) % mod) * n) % mod;
}

void foo() {
    unsigned long long i, res = 1, m = 1000000 , c = 0, j, res1 = 1, mod;
    mod = ceil(pow(10, 9));
    cout << mod << endl;
    long long a = 0, a2 = 0, a5 = 0;
    for (i = 1 ; i <= m; i++) {
        j = i;
        while (j % 10 == 0)
            j /= 10;
        while (j % 2 == 0) {
            j /= 2;
            a2++;
        }
        while (j % 5 == 0) {
            j /= 5;
            a5++;
        }
        res = (res * j ) % mod;
    }

    a = a2 - a5;

    for (i = 1; i <= a; i++)
        res = (res * 2) % mod;
    for (i = 1; i <= 1000000; i++) {
        res1 = (res1 * res) % mod;
    }
    cout << res1 << endl;
}

2 个答案:

答案 0 :(得分:6)

您的平等f(10^12) = (f(10^6))^(10^6)是错误的。 f()基于阶乘,而不是权力。

答案 1 :(得分:0)

您的假设是错误的:

  • f(10 ^ 12) f(10 ^ 6)^(10 ^ 6)不同。
  • 为了获得阶乘的低阶非0位,仅从被乘数中删除1025的所有倍数是不够的。删除10的倍数是个好主意,对于52,只有当另一个被乘数分别为5和2的倍数时,才应删除因子2或5。 / LI>

你应该简化代码并计算模数为10的幂,但10 ^ 9似乎太高,因为 10 ^ 9 * 10 ^ 12 将溢出64位类型unsigned long long