uva 10061 How many zero's and how many digits ?

来源:互联网 发布:windows net snmp 编辑:程序博客网 时间:2024/05/17 18:48

这道题稍微有一点麻烦,求总共占多少个位数比较好解决利用对数就可以轻松得出答案,但是要求最后由多少个0,需要分析一下问题,只要在阶乘的过程中出现了一个基数,就会在最后的结果里面多一个0,所以先将基数分解质因数,看每个质因数究竟需要多少个才能相乘得出一个基数,然后对参与阶乘的n个数分别进行分解,能够提取出基数的质因数的,就将质因数提取出来,统计所有可能提取出的质因数的个数,根据这个统计结果对比形成每一个基数需要的质因数的个数,就可以得出至多能够构成的基数的个数,自然就是最后阶乘的结果中最后包含的0的个数了。我觉得这个思路比较笨,不是一种快速的计算方法,小弟初出茅庐,技能拙劣,欢迎牛人指教更好的方法。

#include <stdio.h>#include <math.h>#include <map>using namespace std;int prime_table[801];typedef int PRIME_FACTOR;typedef int NUMBER;map<PRIME_FACTOR, NUMBER> m, m1;bool is_prime(int n){int i, end;bool f;if(1 == n)return false;end = floor(sqrt((double)n)+0.5);f = true;for(i=2; i<=end; i++){if(0 == n%i){f = false;break;}}return f;}//初始化素数表void init_prime_table(){int i;int count;count = 0;for(i=1; i<=800; i++){if(is_prime(i))prime_table[count++] = i;}}//找出n的所有质因数void get_factor(int n){int i;m.clear();for(i=0; i<=800&&prime_table[i]&&prime_table[i]<=n; i++){if(n == 1)break;if(0 == n%prime_table[i]){n = n/prime_table[i];if(m.find(prime_table[i]) != m.end()){m[prime_table[i]] ++;i = -1;}else{m[prime_table[i]] = 1;i = -1;}}}}void func(int n, int base){get_factor(base);m1.clear();map<PRIME_FACTOR, NUMBER>::iterator it;/*for(it=m.begin(); it!=m.end(); it++){printf("factor=%-10d number=%-10d\n", it->first, it->second);}*/int i;int t, min;for(i=1; i<=n; i++){t = i;for(it=m.begin(); it!=m.end(); it++){loop:if(t == 1)break;if(t%it->first == 0){t = t/it->first;if(m1.find(it->first) != m1.end()){m1[it->first] ++;it = m.begin();goto loop;}else{m1[it->first] = 1;it = m.begin();goto loop;}}}}min = (m1.begin())->second / m.begin()->second;for(it=m.begin(); it!=m.end(); it++){t = (int)(m1[it->first]/it->second);if( min > t )min = t;}//上面的代码是计算最后有几个0,下面的代码利用对数的性质计算结果总共占多少位double sum;sum = 0;for(i=1; i<=n; i++)sum += log((double)i)/log(base);printf("%d %.0lf\n", min, floor(sum)+1);}int main(void){int n, base;init_prime_table();while(scanf("%d %d",&n,&base) != EOF){func(n, base);}return 0;}