您的位置:首页 > 其它

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

2013-09-29 11:22 465 查看
这道题稍微有一点麻烦,求总共占多少个位数比较好解决利用对数就可以轻松得出答案,但是要求最后由多少个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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  acm uva