也许你早就知道阶乘的含义,N阶乘是由1到N相乘而产生,如:
12! = 1 x 2 x 3 x 4 x 5 x 6 x 7 x 8 x 9 x 10 x 11 x 12 = 479,001,600
12的阶乘最右边的非零位为6。
写一个程序,计算N(1<=N<=50,000,000)阶乘的最右边的非零位的值。
注意:10,000,000!有2499999个零。
标签:
单独一行包含一个整数表示最右边的非零位的值。
12
6
传统的暴力解法肯定会超时啊,不过不试试怎么行。果然TLE了,
那么改进下,把末尾的0去掉肯定不会影响结果的吧。
方法一、求出 N! 中5的个数并除掉, 同时出去相同的2的个数。
结果不出所料, 差点就超时了。
#include<iostream> #include <cstdio> using namespace std; int GetFactorNumber(unsigned Number, unsigned Factor) { int result = 0; if(Factor < 2 || Number < 1) return -1; while(Number >= Factor) result += Number /= Factor; return result; } int GetLastDigit(unsigned Number) { int result = 1; int i; int tmp; int Count = 0; int TotalFactors = GetFactorNumber(Number, 5); for(i = Number; i >= 1; i--) { tmp = i; while(tmp % 2 == 0 && Count < TotalFactors) { tmp /= 2; Count++; } while(tmp % 5 == 0) tmp /= 5; tmp %= 10; result *= tmp; result %= 10; } return result; } int main() { int n; scanf("%d", &n); printf("%d\n", GetLastDigit(n)); return 0; }
方法二 、 数论证明的方法, 可查阅文档
具体可自行证明, 改方法时间复杂度为(lg(N))
#include<iostream> #include <cstdio> using namespace std; int GetFactorNumber(unsigned Number, unsigned Factor) { int result = 0; if(Factor < 2 || Number < 1) return -1; while(Number >= Factor) result += Number /= Factor; return result; } int GetLastDigit(unsigned Number) { int result = 1; int i; int tmp; int Count = 0; int TotalFactors = GetFactorNumber(Number, 5); for(i = Number; i >= 1; i--) { tmp = i; while(tmp % 2 == 0 && Count < TotalFactors) { tmp /= 2; Count++; } while(tmp % 5 == 0) tmp /= 5; tmp %= 10; result *= tmp; result %= 10; } return result; } int main() { int n; scanf("%d", &n); printf("%d\n", GetLastDigit(n)); return 0; }
2016-08-11
标签:
原文地址:http://www.cnblogs.com/cshg/p/5762316.html