hdu1066 Last non-zero Digit in N! (factorial last number is not 0)

 

http://acm.hdu.edu.cn/showproblem.php?pid=1066

 

Transfer: https://blog.csdn.net/fengyu0556/article/details/5615129

 

hdu1066 ideas and improved process for the large number of revolutions :()

In order to get rid of 0, we put all the factors 2 and 5 are proposed, into the final reprocessing. ! N of the N number of multiplication can be divided into two stacks: odd and even. Multiplication can be written as the even (2 ^ M) * (M!), M = N DIV 2. M! Recursively do, so just discussed multiplied odd. Consider 1 * 3 * 5 * 7 * 9 * 11 * 13 * 15 * 17 * ... * N (N is an even number, if it is N-1), there is a multiple of 5, 15, 25, 35, ..., 5 of which can be raised into (5 ^ P) * (1 * 3 * 5 * 7 * 9 * ...), the P term in brackets after the CCP, P = (N DIV 5+ 1) DIV 2, and the back of the brackets can continue to put out of 5, recursive processing. now the rest of the numbers are 1 * 3 * 7 * 9 * 11 * 13 * 17 * 19 * .... we only need a few of these their single digits, because (1 * 3 * 9 * 11 * 13 * ...) MOD 10 = (1 * 3 * 7 * 9 * 11 * 13 * ...) MOD 10. we list the remainder table , 131,997,911,319,979 ....... We found that the results of every eight MOD 10 is a cycle. Results odd calculated, we'll look back at the statistics of how many need to take the 2 and 5. After the 2 and 5 are paired N! 0 the latter, see the remaining two have several. If there are remaining 2, consider the digit 2 ^ N is 24862486 ...... four cycles per one digit to identify the rear and front of the result of the multiplication, and then take single digits is the answer. As we complete the additional factor 2 and 5 of treatment, so all of multiplication, only need to calculate the single-digit multiplication, and retain only the result of single digits.

 

 

But I was very surprised: Why I always submit WA? Later I learned that, because of this question of considerable N! Reached 10 ^ 100! Use large numbers to deal with! GPC four compiler switch fully closed, naturally do not check out! And on top of this algorithm into large numbers will be very troublesome. What other good way to do it?

The answer is yes. We set F (N) represents N! Mantissa.

Consider simple. Consider one of N! (N <10), we first proposed that all multiples of five, instead of the position of the original 1 with a multiple of 5. Due to a multiple of 5 have all been put away, so this does not ending in 0 appeared. We list the factorial 0..9 first mantissa (note the position of a multiple of 5 is 1) can be obtained by table [0..9] = (1, 1, 2, 6, 4, 4, 4 , 8, 4, 6). For N <5, direct output table [N] to; for N> = 5, since a proposed 5, and therefore requires a 2 10 paired therewith, i.e. divided by two mantissa. ! Noted that in addition a non-zero number 0 and the last 1 !, factorial must be even, so there is a very special division rule: 2/2 = 6,4 / 2 = 2,6 / 2 = 8,8 / 2 = 4. 2 is special / 2 = 12/2 = 6,6 / 2 = 16/2 = 8 so that we can obtain the following equation:

      table[N]
F(N)= ---------- (0 <= N < 10)
      2^([N/5])

Then consider the complex. Consider one of N! (N> = 10) , we first proposed that all multiples of five, instead of the position of the original 1 with a multiple of 5. Due to a multiple of 5 have all been put away, so this does not ending in 0 appeared. We look at the mantissa product remaining number, table by table, we found that the product of the mantissa is the mantissa number 10 * 6 6,6 or 6, so we will rest into a 10 per group , the rest of the product of the number of mantissa only in the case of the last group of related, that is related to the last digit of N. (Because, according to the last one will be able to know that it is in the first position in several mantissa table, as long as the number of the previous table multiplying the mantissa mantissa get the last group.) Since we propose to a multiple of 5, N! It can be made once [N / 5] a multiple of 5, the number of 5, need to be formulated with the number of 2 10, so the number of 5, the number is divided by 2 will last. 2 results change noted in addition that a four cycle, so if there is a 5 A, except only (A MOD 4) 2 times on it. A MOD 4 with only the last two digits of the relevant A good demand count. The remaining multiple of 5, since 5 have all disposed of, it becomes [N / 5] !. Thus, we can get
a recursive relationship:

      F ([N / 5]) * table [N mantissa]. 6 *
F. (N) = ---------------------------- ------- (N> 10)
          2 ^ ([N /. 5] the MOD. 4)

Thus we get a O (log5 (N)) algorithm divides adder 5 can be made with high precision, and divide by 2 to 10. The whole algorithm is quite clever, it is relatively easy to write.

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define MAXN 10000
 4 int lastdigit(char* buf)
 5 {
 6     const int mod[20]={1,1,2,6,4,2,2,4,2,8,4,4,8,4,6,8, 8 , 6 , 8 , 2 };
7      int len = strlen (buffer), a [Maxnet], i, c, ret = 1 ;
8      if (len == 1 ) return mod [buf [ 0 ] - ' 0 ' ];
9      for (i = 0 ; i <len; i ++) a [i] = buf [len 1 -i] - ' 0 ' ;
10      for (; len; len - =! A [len 1 ])
 11      {
 12          ret = ret * mod [a [ 1 ]% 2*10+a[0]]%5;
13         for (c=0,i=len-1;i>=0;i--)
14             c=c*10+a[i],a[i]=c/5,c%=5;
15     }
16     return ret+ret%2*5;
17 }
18 
19 int main()
20 {
21     char n[10000];
22     while(scanf("%s",n)!=EOF)
23         printf("%d/n",lastdigit(n));
24 }

 

 

 

 

 

 

 

 

 

 

-

Guess you like

Origin www.cnblogs.com/jiamian/p/12238563.html