阶乘的最右边的非零位的值

阶乘问题

题目描述

也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如:
    12! = 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x 11 x 12 = 479,001,600
12的阶乘最右边的非零位为6。
    写一个程序,计算N(1<=N<=50,000,000)阶乘的最右边的非零位的值。
注意:10,000,000!有2499999个零。

输入

仅一行包含一个正整数N。

输出

单独一行包含一个整数表示最右边的非零位的值。

样例输入

12

样例输出

6
传统的暴力解法肯定会超时啊,不过不试试怎么行。果然TLE了,
那么改进下,把末尾的0去掉肯定不会影响结果的吧。
方法一、求出 N! 中5的个数并除掉, 同时出去相同的2的个数。

结果不出所料, 差点就超时了。
#include<iostream>
#include <cstdio>
using namespace std;

int GetFactorNumber(unsigned Number, unsigned Factor) {
    int result = 0;
    if(Factor < 2 || Number < 1)
        return -1;
    while(Number >= Factor)
        result += Number /= Factor;
    return result;
}


int GetLastDigit(unsigned Number) {
    int result = 1;
    int i;
    int tmp;
    int Count = 0;
    int TotalFactors = GetFactorNumber(Number, 5);
    for(i = Number; i >= 1; i--) {
        tmp = i;
        while(tmp % 2 == 0 && Count < TotalFactors) {
            tmp /= 2;
            Count++;
        }
        while(tmp % 5 == 0)
            tmp /= 5;
        tmp %= 10;
        result *= tmp;
        result %= 10;
    }
    return result;
}
int main() {
    int n;
    scanf("%d", &n);
    printf("%d
", GetLastDigit(n));
    return 0;
}
View Code

方法二 、 数论证明的方法, 可查阅文档

具体可自行证明, 改方法时间复杂度为(lg(N))

#include<iostream>
#include <cstdio>
using namespace std;

int GetFactorNumber(unsigned Number, unsigned Factor) {
    int result = 0;
    if(Factor < 2 || Number < 1)
        return -1;
    while(Number >= Factor)
        result += Number /= Factor;
    return result;
}


int GetLastDigit(unsigned Number) {
    int result = 1;
    int i;
    int tmp;
    int Count = 0;
    int TotalFactors = GetFactorNumber(Number, 5);
    for(i = Number; i >= 1; i--) {
        tmp = i;
        while(tmp % 2 == 0 && Count < TotalFactors) {
            tmp /= 2;
            Count++;
        }
        while(tmp % 5 == 0)
            tmp /= 5;
        tmp %= 10;
        result *= tmp;
        result %= 10;
    }
    return result;
}
int main() {
    int n;
    scanf("%d", &n);
    printf("%d
", GetLastDigit(n));
    return 0;
}
View Code


2016-08-11
原文地址:https://www.cnblogs.com/cshg/p/5762316.html