zoukankan      html  css  js  c++  java
  • 阶乘的最右边的非零位的值

    阶乘问题

    题目描述

    也许你早就知道阶乘的含义,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
  • 相关阅读:
    基础C语言知识串串香7☞位操作
    史上z..zui难回答的26个问题(1)
    基础C语言知识串串香6☞内存大话题
    基础C语言知识串串香5☞如何避免回绕和溢出
    基础C语言知识串串香4☞注意隐形提升带来的C陷阱
    基础C语言知识串串香3☞size_t类型
    基础C语言知识串串香1☞基本数据类型
    基础C语言知识串串香2☞char类型变量种种
    Linux
    Ubunt_配置_网易的源
  • 原文地址:https://www.cnblogs.com/cshg/p/5762316.html
Copyright © 2011-2022 走看看