您的位置:首页 > 其它

UVa 10061 - How many zero's and how many digits ?

2014-04-27 20:51 337 查看
传送门UVa 10061 - How many zero's and how many digits
?


数论的题目. 

一开始想用Java混过去的, 不过TLE了. 想想也是, 要是这样都能过那也太水了...

后来参考了@BearChild@SIO__Five的解题报告,
总算搞懂了.


题意是给一个n和一个进制, 求n!在此进制下的位数和0的数目.
先求0的数目.
这里他们已经讲得很详细了. 引用一下.

1. 求一个数 n 的阶乘在 b 进制下有多少位,必有 b^(m-1)<n!<b^m。把b换成10就很好理解。所以 m = log b(n!)=log b(1)+log b(2) +…… + log b(n)+1 要注意一下精度问题。

2. 求n!按照b进制转换后,末尾有几个零,
就是求n!可以整除几个b. 同样的想法,把b分解成质因数相乘,比如16=2*2*2*2,然后记录n!当中b的质因数的个数,最后再反过来处理。


补充一下上面那点, 意思就是统计出n的所有质因数的数目, 然后把base的也分解出来, 有一个相同的质因数就把对应的质因数的数量减去1. 如果哪个先减完了, 就是可以整除几个...哎...我还是表达不出来.

详情见代码

#include <cstdio>
#include <cmath>
#include <cstring>

using namespace std;

int prime[2000];
int n, base;

int GetDigit();
int GetZero();

int main()
{
//freopen("input.txt", "r", stdin);
while (~scanf("%d%d", &n, &base))
{
memset(prime, 0, sizeof(prime));
int digit = GetDigit();
int zero = GetZero();
printf("%d %d\n", zero, digit);
}
return 0;
}

int GetDigit()
{
int i;
double sum = 0;
for (i = 1; i <= n; i++)
{
sum += log(i);
}
sum /= log(base);
return floor(sum + 1e-9) + 1;
}

int GetZero()
{
//先分解在base进制下的n.
int i, j, temp, ans = 0;
for (i = 2; i <= n; i++)
{
temp = i;
for (j = 2; j <= base && j <= temp; j++)
{
while (temp % j == 0)
{
prime[j]++;
temp /= j;
}
}
}
//接下来分解base.
while (true)
{
temp = base;
for (i = 2; i <= base; i++)
{
while (temp % i == 0)
{
if (prime[i] == 0)
return ans;
else
{
prime[i]--;
temp /= i;
}
}
}
ans++;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM UVa 10061