The algorithm of factorial is more than two aspects: first, high precision computation and the second is related to number theory.

First, the high precision calculation factorial

This is actually the least technical content of the problem, but will often use, so still have to write, optimize its calculations.

First look at the factorial calculation less than or equal to 12 (the calculation will not exceed the 32-bit range):

int factorial (int n) {

if (n = = 1 | | n = = 0)

return 1;

return factorial (n-1) *n;

}

This recursive procedure is simple and straightforward, very intuitive, however, once n > 12, the range of more than 32-bit int is wrong, so the above recursive program is only suitable for the factorial calculation of N <= 12, in order to compute the factorial of larger n, we need to incorporate the high precision multiplication algorithm into factorial calculation, The high-precision multiplication process can be described as follows: (where A * B = c,a[0], b[0], c[0] store the length separately)

for (i = 1; I <= a[0]; i++)

for (j = 1; J <= B[0]; J + +) {

C[i+j-1] + = a[i]*b[j]; Current i+j-1-bit counterpart + a[i] * B[j]

C[I+J] + = C[I+J-1]/10; Its latter one + its quotient (carry)

C[I+J-1]%= 10; It's more than I can take.

}

C[0] = a[0] + b[0];

while (C[0] > 1 && c[c[0]] = = 0) c[0]--; Go to the first 0, get the actual C length

With this high-precision multiplication, the calculation of the factorial can be done in a simple iteration:

for (i = 2; I <= N; i++) {

Convert I to an array of characters;

Perform a high precision multiplication: Multiply the last result by I

}

Second, related to the number theory

As factorial to the back of the more and more large, clever use of number theory to find some interesting numbers (numerical), such as the design point of factorial algorithm, the following gives a number of related problems and analysis:

(1) Calculate the first non-0 digits at the end of the factorial:

This is a relatively classic problem, the more complex algorithm is to use a difficult mathematical formula, unfortunately I will not, from the online data learning, sorted out the following simple and understandable algorithm:

Observing n!, it can be found that in the multiplication process, for any n > 1,n! at the end of the first 0 digits are even. We just have to keep the last one zero. When the number to multiply contains the factor 5 o'clock, we can take all factor 5 as 8来 multiply. This is because:

... x2*5= ... 10 (homes) or ... 60, the last zero is 6. And just 2*8=16, the bottom is 6.

... x4*5= ... 70 (homes) or ... 20, the last zero is 2. And just 4*8=32, the bottom is 2.

... x6*5= ... 30 (homes) or ... 80, the last zero is 8. And just 6*8=48, the bottom is 8.

... x8*5= ... 90 (homes) or ... 40, the last zero is 4. And just 8*8=64, the bottom is 4.

(For n > 1 o'clock, the last one does not appear 1, 7, 3, 9, and is always the cycle of 2, 4, 6, 8)

Therefore, in the iterative multiplication, the main is to calculate the number of factor 5, while the number of factors 5 can be seen in 4 as a circular section (that is, only the number of it needs to take modulo 4). Then for the number of factor 5 in different cases, you can pass res[5][4] = {{0,0,0,0}, {2,6,8,4}, {4,2,6,8}, {6,8,4,2}, {8,4,2,6}} to come, use Nonzero[i to represent the last of the factorial of I, So:

If T is an even number, direct multiplication: nonzero[i] = (nonzero[i-1]*t)%10.

otherwise nonzero[i] = res[((nonzero[i-1]*t)%10)/2][five];

where T is the result of removing all factor 5, five is the modulus of factor 5 to 4.

(2). How many 0 at the end of factorial

The analysis found that, in fact, the end of 0, is the number of factor 5, and the calculation of 1~n between the number of a factor I is a simple algorithm is:

CNT = 0; while (n) {n/= i; cnt + = n;}

Therefore, the direct conversion of I to 5, you can get the number of factor 5, that is, the number of n! at the end of 0.

(3). Returns the second digit to the left of the factorial

Simple algorithm: Multiply by the real number, over 100 divided by 10, and finally take a bit. Because the integer part is the second number to the left of the factorial result. Related Topics:

(4). Determine whether the value M can be divisible n!

Algorithm: Using the element factor to judge the method

A. Direct output of two special cases first:

m = = 0 Then 0 will certainly not divide n!;

N >= m is sure to divide n!;

B. Then there is only one last situation: M > N, we pick up from the least element factor of M, the nums1 factor I can obtain the number of the element I of M, then check the number of the closed interval I ~ n, and how many elements I can be used to make use of the mathematical formula described above (2). Row calculations get NUMS2. If Nums2 < nums1, which means the number of elements in 1 ~ N < The number of divisor m containing the factor I, then M must not divide n!, set ok = False.

C. Finally: if!ok or M > n or M = = 0 are not divisible, you can divide

(5). The number n can be expressed as a number of different factorial and:

Here you can choose the factorial: 0! ~ 9!, in fact, this problem is irrelevant to number theory, and search-related.

Analysis, the DFS search can be used directly because of the low number of factorial options available:

A. First the factorial of 0 ~ 9 as a table a[10], and then set up an array of "and" ans[n].

B. Depth-First search method:

Search (n) {

for (i = n; I <= 9; i++) {

Sum + + a[i]; Sum

If sum does not exist in the ANS array, the sum is inserted into the ans[] array

Search (n+1);

Sum-= a[i]; Backtracking

}

}

C. Finally, for input n, find out if n exists in the ANS array, and if it does, it means that n can be expressed as a different factorial and otherwise not.