Hdu 1066 Last non-zero Digit in N! (Number Theory -- n! ), Hdunon-zero
Last non-zero Digit in N!
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission (s): 6432 Accepted Submission (s): 1593
Problem DescriptionThe expression N !, Read as "N factorial," denotes the product of the first N positive integers, where N is nonnegative. So, for example,
N!
0 1
1 1
2 2
3 6
4 24
5 120
10 3628800
For this problem, you are writing a program that can compute the last non-zero digit of the factorial for N. for example, if your program is asked to compute the last nonzero digit of 5 !, Your program showould produce "2" because 5! = 120, and 2 is the last nonzero digit of 120.
InputInput to the program is a series of nonnegative integers, each on its own line with no other letters, digits or spaces. for each integer N, you should read the value and compute the last nonzero digit of N !.
OutputFor each integer input, the program shocould print exactly one line of output containing the single last non-zero digit of N !.
Sample Input
1 2 26 125 3125 9999
Sample Output
124828
SourceSouth Central USA 1997
Question: N! Is not 0.
Resolution:
N is required for this question! The last non-zero number of, if the general practice, first count the number of 2 and 5, then
Then multiply by 2 to get the TLE. Therefore, we need to simplify the process:
In order to remove 0, we put forward all the factors 2 and 5 and put them to the end for further processing. N! N
The number can be divided into two heaps: an odd number and an even number. You can write (2 ^ M) * (M!) by multiplying an even number !), M = n div 2. M! Yes
Recursive processing, so now we only need to discuss the multiplication of odd numbers. Consider 1*3*5*7*9*11*13*15*17 *... * N (if
N is an even number is a N-1), here is the multiples of 5 are 5, 15, 25, 35,..., which can be 5 proposed
, To (5 ^ P) * (1*3*5*7*9 *...), P is enclosed in brackets, P = (n div 5 + 1) DIV 2, and then
The brackets can be further raised to 5 for Recursive processing. The remaining number is 1*3*7*9*11*13.
* 17*19 *.... We only need their single digits because (1*3*9*11*13
*...) MOD 10 = (1*3*7*9*1*3 *...) MOD 10. We list the remainder table,
1 3 1 9 9 7 9 1 1 3 1 9 9 7 9 ....... We found that every eight MOD 10 results in a loop.
After calculating the odd number of results, let's look back at the number of 2 and 5 to be multiplied. Pairing 2 and 5 is all N.
! The value 0 is followed by the number 2. If the remaining two exist, consider that the single digit of 2 ^ N is 2 4 8 6 2 4
8 6 ...... Every four items have a loop. After finding this single digit, multiply it with the previous result.
Answer. Because we fully process the two and five factors separately, in all multiplication, we only need to calculate the single-digit multiplication and only keep the single-digit result.
But what surprised me is: Why do I always submit WA? I learned later that the reason is that N is quite large.
! Reached 10 ^ 100! Use a large number for processing! The four compilation Switches of GPC are completely off. Naturally, they cannot be found! And
The above algorithm is difficult to replace with a large number. Is there any other good method?
The answer is yes. Let's set F (N) to N! .
First, consider simple. Consider a certain N! (N <10), we first propose the multiples of all 5, and use 1 to replace the original
The position in multiples of 5. Because the multiples of 5 are all removed, so there will be no ending number 0. First
The ending number of the factorial of 0 .. 9 is listed (note that the position of the multiples of 5 is 1). You can get table [0 .. 9] =
(1, 1, 2, 6, 4, 4, 4, 8, 4, 6 ). For N <5, directly output table [N]. For N>
= 5. Because a 5 is proposed, a 2 is required to be matched with 10, that is, dividing the ending number by 2. Note that except 0
! And 1 !, The last non-zero number of a factorial must be an even number, so there is a special division rule: 2/2
= 6, 4/2 = 2, 6/2 = 8, 8/2 = 4. 2/2 = 12/2 = 6,
6/2 = 16/2 = 8. In this way, we can get the following formula:
Code:
Table [N]
F (N) = ------------ (0 <= N <10)
2 ^ ([N/5])
Consider complicated ones. Consider a certain N! (N> = 10), we first propose the multiples of all 5, and use 1 to replace the original
In multiples of 5. Because the multiples of 5 are all removed, so there will be no ending number 0. View
Check the ending number of the product of the remaining number. Through the table, we find that the ending number of the product of the 10 numbers is 6,
The ending number of 6*6 is 6, so we divide the remaining number into a group every 10, then the ending number of the product of the remaining number
It is only related to the last group, that is, the last digit of N. Because we have raised the multiples of 5
, N! In one request, we can propose a multiple of [N/5] to five. If there is a number of five, we need to assign the number of two to ten.
Divide the number of five by the number of two. Note that the result of Division 2 changes to four loops, so if
There is A 5, you only need to divide (a mod 4) Twice 2. A mod 4 is only related to the last two digits of.
. The number of the remaining 5 is [N/5] Because all 5 has been processed. So we can get
A recursive relationship:
Code:
F ([N/5]) * table [ending number of N] * 6
F (N) = ----------------------------------- (N> 10)
2 ^ ([N/5] MOD 4)
In this way, we get an O (log5 (N) algorithm. The Division of 5 can be done with a high-precision addition. Multiply by 2 and then divide 10.
Yes. The entire algorithm is quite clever and easy to write.
Because 2 ^ N is a 4-loop section
In addition, table [N] uses 10 as the cyclic section.
So starting from 10
F ([N/5]) * table [ending number of N] * 6
F (N) = ----------------------------------- (N> 10)
2 ^ ([N/5] MOD 4)
In addition to F [n/5], the formula on the right is circular section 20.
Write the number mod [20] = {,} at the end of the loop}
This is the overall idea.
Note: The above analysis draws from the unknown blog
AC code:
#include<stdio.h>#include<string.h>int mod[20]={1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8,8,6,8,2};char n[1000];int a[1000];int main(){ int i,c,t,len; while(scanf("%s",n)!=EOF) { t=1; len=strlen(n); for(i=0;i<len;i++) a[i]=n[len-1-i]-'0'; while(len) { len-=!a[len-1]; t=t*mod[a[1]%2*10+a[0]]%10; for(c=0,i=len-1;i>=0;i--) c=c*10+a[i],a[i]=c/5,c%=5; } printf("%d\n",t); } return 0;}