UVA 10061 How many zeros and how many digits?

来源:互联网 发布:会计课程 知乎 编辑:程序博客网 时间:2024/06/05 04:43

How many zeros and how many digits?

Input: standard input

Output: standard output


Given a decimal integer number you will have to find out how many trailing zeros will be there in its factorial in a given number system and also you will have to find how many digits will its factorial have in a given number system? You can assume that for a b based number system there are b different symbols to denote values ranging from 0 ... b-1.


Input

There will be several lines of input. Each line makes a block. Each line will contain a decimal number N (a 20bit unsigned number) and a decimal number B (1<B<=800), which is the base of the number system you have to consider. As for example 5! = 120 (in decimal) but it is 78 in hexadecimal number system. So in Hexadecimal 5! has no trailing zeros


Output

For each line of input output in a single line how many trailing zeros will the factorial of that number have in the given number system and also how many digits will the factorial of that number have in that given number system. Separate these two numbers with a single space. You can be sure that the number of trailing zeros or the number of digits will not be greater than 2^31-1


Sample Input:

2 10
5 16
5 10

 

Sample Output:

0 1
0 2

1 3


给定两个数。一个为n,一个为m进制

要求出n的阶乘在m进制下末尾0的个数和总位数。


题目一共有2个问题。

一、求总位数

举个例子 一个三位数n 满足10^2 <= n < 10^3

那么他的位数w 满足 w = lg10^3 = 3。 因此只要求lgn 向下取整 +1就是位数。。

然后因为阶乘比如5阶乘的话是5 * 4 * 3 * 2 * 1。他的位数就满足lg 5 * 4 * 3 * 2 * 1 = lg5 + lg4 + lg3 + lg2 + lg1

用相加的就不会超过数字上限。

当然这是十进制下得。如果是m进制下 ,就把lgn 换成logm(n)就可以了。 logm(n)的表示方法是 lgn / lgm。高中数学的知识。。 这里有个double向下取整精度的问题要注意。。。转换成int时候,要floor(算出来的位数 + 1e-9) + 1.

最后得出

位数的计算方式为:floor(logm(n) + logm(n - 1) + ...+ logm(1) + 1e-9) + 1.

二、求末尾0的总个数

如果是m进制。那么当他的n阶乘中,遇到一个因子相乘等于m的时候就会多一个0.

举个例子。如果10进制。那么遇到2 * 5 或者 10就会末尾多一个0.。

直接存因子不太好实现。因此转换为把n阶乘中所有因子都转换成质因子。存在一个数组里。

然后在根据他是m进制。用这个数组里的质因子去组合。每次组合出一个质因子,0的个数就多1.

组合到不能组合为止。。这时候0的个数就是末尾0的个数。

要注意:由于题目最多是800进制的数。也就是因数不会超过800。因此数组不用开很大。所以在查找质因子的时候要注意。n中可能有超过800的质因子。这些没必要存。


代码:

#include <stdio.h>#include <string.h>#include <math.h>int n , jin;int fen[1000];double wsum;int wwsum;int zsum;int sbi;int jini;int main(){    while (scanf("%d%d", &n, &jin) != EOF)    {memset(fen, 0, sizeof(fen));wsum = 0.0;zsum = 0;for (int i = 2; i <= n; i ++){    wsum += log10(i);}    wsum /= log10(jin);wwsum = floor(wsum + 1e-9) + 1;for (int i = 2; i <= n; i ++){    sbi = i;    for (int j = 2; j <= sbi && j <= jin; j ++)    {while (sbi % j == 0){    fen[j] ++;    sbi /= j;}    }}while (1){    jini = jin;    for (int i = 2; i <= jini; i ++)    {while (jini % i == 0){    if (fen[i] > 0)    {fen[i] --;    }    else    {goto out;    }    jini /= i;}    }    zsum ++;}out:printf("%d %d\n", zsum, wwsum);    }    return 0;}





原创粉丝点击