📜  阶乘的最后一个非零数字

📅  最后修改于: 2021-04-30 03:12:13             🧑  作者: Mango

给定数字n,请找到n!中的最后一个非零数字。

例子:

Input  : n = 5
Output : 2
5! = 5 * 4 * 3 * 2 * 1 = 120
Last non-zero digit in 120 is 2.

Input  : n = 33
Output : 4

一个简单的解决方案是首先找到n !,然后找到n的最后一个非零数字。由于算术溢出,该解决方案即使对于较大的数字也不起作用。

更好的解决方案基于以下递归公式

Let D(n) be the last non-zero digit in n!
If tens digit (or second last digit) of n is odd
    D(n) = 4 * D(floor(n/5)) * D(Unit digit of n) 
If tens digit (or second last digit) of n is even
    D(n) = 6 * D(floor(n/5)) * D(Unit digit of n)

公式说明:
对于小于10的数字,我们可以通过上述简单的解决方案轻松地找到最后一个非零数字,即先计算n !,然后找到最后一个数字。
D(1)= 1,D(2)= 2,D(3)= 6,D(4)= 4,D(5)= 2
D(6)= 2,D(7)= 4,D(8)= 2,D(9)= 8。

D(1) to D(9) are assumed to be precomputed.

Example 1: n = 27 [Second last digit is even]:
D(27) = 6 * D(floor(27/5)) * D(7)
      = 6 * D(5) * D(7)
      = 6 * 2 * 4 
      = 48
Last non-zero digit is  8

Example 2: n = 33 [Second last digit is odd]:
D(33) = 4 * D(floor(33/5)) * D(3)
      = 4 * D(6) * 6
      = 4 * 2 * 6
      = 48
Last non-zero digit is  8

以上公式如何运作?
下面的解释提供了公式背后的直觉。读者可以参考http://math.stackexchange.com/questions/130352/last-non-zero-digit-of-a-factorial以获得完整的证明。

14! = 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 
                     6 * 5 * 4 * 3 * 2 * 1

Since we are asked about last non-zero digit, 
we remove all 5's and equal number of 2's from
factors of 14!.  We get following:

14! = 14 * 13 * 12 * 11 * 2 * 9 * 8 * 7 *
                           6 * 3 * 2 * 1

Now we can get last non-zero digit by multiplying
last digits of above factors!

在n!中,2的数量总是大于5的数量。要删除尾随的0,我们将删除5和相等的2。

a = floor(n / 5), b = n%5。在除去相等数量的5和2之后,我们可以从n减少问题!到2*一个! * b!

D(n)= 2 a * D(a)* D(b)

执行:

C++
// C++ program to find last non-zero digit in n!
#include
using namespace std;
  
// Initialize values of last non-zero digit of
// numbers from 0 to 9
int dig[] = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8};
  
int lastNon0Digit(int n)
{
     if (n < 10)
        return dig[n];
  
    // Check whether tens (or second last) digit
    // is odd or even
    // If n = 375, So n/10 = 37 and (n/10)%10 = 7
    // Applying formula for even and odd cases.
    if (((n/10)%10)%2 == 0)
        return (6*lastNon0Digit(n/5)*dig[n%10]) % 10;
    else
        return (4*lastNon0Digit(n/5)*dig[n%10]) % 10;
}
  
// Driver code
int main()
{
    int n = 14;
    cout << lastNon0Digit(n);
    return 0;
}


Java
// Java program to find last 
// non-zero digit in n!
  
class GFG
{
    // Initialize values of last non-zero digit of
    // numbers from 0 to 9
    static int dig[] = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8};
      
    static int lastNon0Digit(int n)
    {
        if (n < 10)
            return dig[n];
      
        // Check whether tens (or second last) 
        // digit is odd or even
        // If n = 375, So n/10 = 37 and 
        // (n/10)%10 = 7 Applying formula for
        // even and odd cases.
        if (((n / 10) % 10) % 2 == 0)
            return (6 * lastNon0Digit(n / 5)
                    * dig[n % 10]) % 10;
        else
            return (4 * lastNon0Digit(n / 5) 
                    * dig[n % 10]) % 10;
    }
      
    // Driver code
    public static void main (String[] args)
    {
        int n = 14;
        System.out.print(lastNon0Digit(n));
    }
}
// This code is contributed by Anant Agarwal.


Python3
# Python program to find
# last non-zero digit in n!
  
# Initialize values of
# last non-zero digit of
# numbers from 0 to 9
dig= [1, 1, 2, 6, 4, 2, 2, 4, 2, 8]
   
def lastNon0Digit(n):
    if (n < 10):
        return dig[n]
   
     # Check whether tens (or second last) digit
     # is odd or even
     # If n = 375, So n/10 = 37 and (n/10)%10 = 7
     # Applying formula for even and odd cases.
    if (((n//10)%10)%2 == 0):
        return (6*lastNon0Digit(n//5)*dig[n%10]) % 10
    else:
        return (4*lastNon0Digit(n//5)*dig[n%10]) % 10
    return 0
  
# driver code
n = 14
  
print(lastNon0Digit(n))
  
# This code is contributed
# by Anant Agarwal.


C#
// C# program to find last 
// non-zero digit in n!
using System;
  
class GFG {
      
    // Initialize values of last non-zero 
    // digit of numbers from 0 to 9
    static int []dig = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8};
      
    static int lastNon0Digit(int n)
    {
        if (n < 10)
            return dig[n];
      
        // Check whether tens (or second 
        // last) digit is odd or even 
        // If n = 375, So n/10 = 37 and 
        // (n/10)%10 = 7 Applying formula 
        // for even and odd cases.
        if (((n / 10) % 10) % 2 == 0)
            return (6 * lastNon0Digit(n / 5) *
                    dig[n % 10]) % 10;
        else
            return (4 * lastNon0Digit(n / 5) *
                    dig[n % 10]) % 10;
    }
      
    // Driver code
    public static void Main ()
    {
        int n = 14;
        Console.Write(lastNon0Digit(n));
    }
}
  
// This code is contributed by Nitin Mittal.


PHP


输出:

2