The factorial of an integer N, written N!, is the product of all the integers from 1 through N inclusive. The factorial quickly becomes very large: 13! is too large to store in a 32-bit integer on most computers, and 70! is too large for most floating-point variables. Your task is to find the rightmost non-zero digit of n!. For example, 5! = 1 * 2 * 3 * 4 * 5 = 120, so the rightmost non-zero digit of 5! is 2. Likewise, 7! = 1 * 2 * 3 * 4 * 5 * 6 * 7 = 5040, so the rightmost non-zero digit of 7! is 4.
PROGRAM NAME: fact4
INPUT FORMAT
A single positive integer N no larger than 4,220.
SAMPLE INPUT (file fact4.in)
7
OUTPUT FORMAT
A single line containing but a single digit: the right most non-zero digit of N! .
SAMPLE OUTPUT (file fact4.out)
4
题解:最先想着高精度。。不过人太懒,不想写。突然想到在产生一个0之后,之后每个数乘以位置的数为0都将产生0,如果要继续产生0那么需要乘以10或者10的倍数。所以在每次相乘之后都对一个模取余就行。我用的模是100000000.。。果断WA了。。。不过题解也是我这样的,只是模是10000。。。然后我也就改小成10000,然后就AC了。。。好猥琐。。。
1 /* 2 ID:spcjv51 3 PROG:fact4 4 LANG:C 5 */ 6 #include<stdio.h> 7 #define MAXS 100000 8 int main(void) 9 { 10 freopen("fact4.in","r",stdin); 11 freopen("fact4.out","w",stdout); 12 int n,i,ans; 13 scanf("%d",&n); 14 ans=1; 15 for(i=1;i<=n;i++) 16 { 17 ans=(ans*i)%MAXS; 18 while(ans%10==0) ans/=10; 19 } 20 printf("%d\n",ans%10); 21 return 0; 22 }
应该是要用官方的方法才是正确的,也比较好理解。因为要产生10,才会产生0,10肯定是2*5产生的。所以我们计算一下因子5的个数,再统计一下因子2的个数。成对的消除2和5.最后答案就是次数的最后一位,即%10即可。
The insight for this problem is that 0's at the end of a number come from it being divisible by 10, or equivalently, by 2 and 5. Furthermore, there are always more 2s than 5s in a factorial.
To get the last digit of the factorial, we can run a loop to calculate it modulo 10, as long as we don't include any 2s or 5s in the product. Of course, we want to exclude the same number of 2s and 5s, so that all we're really doing is ignoring 10s. So after the loop, we need to multiply in any extra 2s that didn't have 5s to cancel them out.
/* PROG: fact4 ID: rsc001 */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> void main(void) { FILE *fin, *fout; int n2, n5, i, j, n, digit; fin = fopen("fact4.in", "r"); fout = fopen("fact4.out", "w"); assert(fin != NULL && fout != NULL); fscanf(fin, "%d", &n); digit = 1; n2 = n5 = 0; for(i=2; i<=n; i++) { j = i; while(j%2 == 0) { n2++; j /= 2; } while(j%5 == 0) { n5++; j /= 5; } digit = (digit * j) % 10; } for(i=0; i<n2-n5; i++) digit = (digit * 2) % 10; fprintf(fout, "%d\n", digit); exit(0); }