1、做到这么水的题真感动啊。。。刚开始以为要用高精度乘法,吓坏了。。。其实不用,只要保留最后几位就可以了(注意不是保留最后一位),因为可能与两位数相乘的时候,前面进位使得最后为0,要是不保存前几位,乘后的结果就不对了。。。
2、还要注意,最后输出的时候只输出一位。。。我刚开始忘了,WA一次。。。
/*
ID:mrxy564
PROG:fact4
LANG:C++
*/
#include<cstdio>
using namespace std;
int main(){
freopen("fact4.in","r",stdin);
freopen("fact4.out","w",stdout);
int n,ans=1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
ans*=i;
while(ans%10==0) ans/=10;
ans%=10000;
}
printf("%d\n",ans%10);
return 0;
}
官方题解:
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); }