当前位置: 代码迷 >> 综合 >> UVA 10061 - How many zero‘s and how many digits ?
  详细解决方案

UVA 10061 - How many zero‘s and how many digits ?

热度:58   发布时间:2023-12-24 11:24:17.0

题目大意:输入n,m。求n!在m进制中末尾有几个零,以及为几位数。

解题思路:林炜大佬打得代码。。。漂亮。n!在m进制有几位,卡精度,用斯特林公式wa了。用对数求,加上1e-9才过。对数求法是这样的。。。设结果为X位数,那么n!< m^X。所以X = logm(n!) = logm (2) + ...logm(n)。而末尾0的求法,是求出m的质因数,然后算2~n,能被不同的m质因数整除的为质因数的几倍,取最少的,则为末尾的0。例如:5 16。16 = 2 * 2 * 2 * 2。2~5只有2、4可以被2整除,一共3个2。要求4个2才能一个0。所以末尾没有0。

ac代码:

#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
int n, k, cnt, num, m;
int vis[2000005], mark[2000005];
double zero;
int main()
{while (scanf("%d%d", &n, &k)!=EOF){memset(vis, 0, sizeof(vis));memset(mark, 0, sizeof(mark));zero = 0; if ( !n || n == 1)zero = 1;else{for (int i = 2; i <= n; i++)zero += log(i);zero  = floor( zero/log(k) + 1e-9 ) + 1; }		m = k;	for(int i = 2; i <= k; i++)while(k%i==0){vis[i]++;k /= i;}for(int i = 2; i <= n; i++){int d =sqrt(i);int s = i;for(int j = 2; j <= d; j++)while(s % j==0){mark[j]++;s/=j;}mark[s]++;}int cnt = 99999999;for(int i = 1; i <= m; i++)if(vis[i])cnt = min(mark[i]/vis[i],cnt);printf("%d %.0lf\n", cnt, zero);}
return 0;
}

大佬手打质数表,存一份:

for(int i = 2; i <= 800; i++)if(!p[i]){p[++p[0]] = i;for(int j = 2*i; j <= 800; j+=i)p[j] = 1;	}
  相关解决方案