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

来源:互联网 发布:龙少微软软件工作室 编辑:程序博客网 时间:2024/05/17 02:26

传送门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++;    }}




0 0