First, this question requires that the first ending number of the factorial result of a given number is not 0, which requires us to sum up a certain law through the nature of the factorial. Second, because the number required for the question is large, Java can be used to solve high-precision data.
Original link http://blog.csdn.net/rappy/article/details/1903360
First, for the Series D [10] = {1, 1, 2, 3, 4, 1, 6, 7, 8, 9} and
FF [10] = {1, 1, 2, 6, 4, 4, 4, 8, 4, 6}
D [0] *... * d [I] % 10 = FF [I], 0 <= I <10.
For n <5, directly output FF [N.
For N> = 5, for example, n = 26,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
The product of is equal
1 2 3 4 1 6 7 8 9 1 11 12 13 14 1 16 17 19 1 21 22 23 24 1 26
The product of is multiplied by the product of 5 10 15 20 25, while the product of 5 10 15 20 25 is equal
1 ~ The product of 26/5 is multiplied by 526/5.
First consider
1 2 3 4 1 6 7 8 9 1 11 12 13 14 1 16 17 18 19 1 21 22 23 24 1 26,
It can be divided into dozens of groups.
Among them, 1 2 3 4 1 6 7 8 9, 11 12 13 14 1 16 17 18 19 1 product of the two groups
They are in the form of 10 * q + 6, and the two products are multiplied by 10 * q + 6.
The product of the number of 21 22 23 24 1 26 is 10 * q + FF [26% 10] = 10 * q + 4,
Therefore, the product of the number of three groups is 10 * q + 4, which is derived from FF [26% 10] * 6% 10.
So 26! = (26/5 )! * 526/5*(10 * q + 4) = (26/5 )! * 1026/5*[(10 * q + 4)/226/5],
Then 26! The last non-zero number of IS (26/5 )! * [(10 * q + 4)/226/5].
Note that except 0! And 1 !, The last non-zero number of a factorial must be an even number, so there is a rule:
(10 * q + 2)/2 = 10 * Q' + 6
(10 * q + 6)/2 = 10 * Q' + 8
(10 * q + 8)/2 = 10 * Q' + 4
(10 * q + 4)/2 = 10 * Q' + 2
Each time you divide the number by two or four times, the ending number will be cyclically once. Therefore
(10 * q + 4)/226/5 of the ending number (10 * q + 4)/226/5% 4, which can be calculated using the following code:
T = FF [n % 10] x 6% 10;
For (INT I = 1; I <= N/5% 4; I ++)
{
If (t = 2 | T = 6) T + = 10;
T/= 2;
}
The calculated T is the ending number of (10 * q + 4)/2 ^ (26/5), and then multiply it by (26/5 )! End
If a non-zero number is used to modulo 10, 26 is displayed! Calculate the last non-zero number of (26/5 )! End
A non-zero number can be recursively processed.
In summary, set F (n) to n! The last non-zero number has the following recursion:
F (n) = FF [N] (n <5)
F ([N/5]) * FF [the ending number of N] * 6
F (n) = ----------------------------------- (n> = 5)
2 [N/5] % 4
Therefore, the time complexity of the algorithm is O (log5n.
Even if n reaches 10100, it can be quickly calculated. However, a high-precision integer is required, namely, Division 5.
Multiply by 2, divide by 10, and multiply by 2, that is, auto-increment. Divide by 10, that is, cut off the last digit.
To modulo 4, you only need to modulo 4 with the last two digits, for example, 1234% 4 = 34% 4 = 2.
Therefore, the implementation is quite convenient.
# Include <cstdio>
Using namespace STD;
Const int FF [10] = {1, 1, 2, 6, 4, 4, 4, 8, 4, 6 };
Int F (int n)
{
If (n <5) return FF [N];
Int T = FF [n % 10] * 6% 10;
For (INT I = 1, R = N/5% 4; I <= r; I ++)
{
If (t = 2 | T = 6) T + = 10;
T/= 2;
}
Return F (N/5) * T % 10;
}
Int main ()
{
Int N;
While (scanf ("% d", & N )! = EOF)
{
Printf ("% 5D-> % d", N, F (n ));
}
Return 0;
}
Java solution:
import java.util.*;import java.math.*;public class Main{ static int [] hash = {6, 6, 2, 6, 4, 4, 4, 8, 4, 6}; static int [] one_digit_hash = {1, 1, 2, 6, 4, 2, 2, 4, 2, 8}; static BigInteger five = BigInteger.valueOf(5),four=BigInteger.valueOf(4),ten=BigInteger.valueOf(10); public static int calc(BigInteger num) { if(num.compareTo(ten)==-1) return one_digit_hash[(int)num.longValue()]; else { int mod = (int)num.divide(five).mod(four).longValue(); String str = num.toString(); int ret = hash[str.charAt(str.length()-1)-'0']; ret=ret*calc(num.divide(five)) % 10; while(mod-- >0) ret=ret*8%10; return ret; } } public static void main(String[] args) { Scanner cin =new Scanner (System.in); BigInteger num; while(cin.hasNextBigInteger()) { num=cin.nextBigInteger(); System.out.println(calc(num)); } }}