这道题有点考精度啊 自己没用精度算的M 出错了 然后贴别人用精度算的就过了
求m的公式是 B^m-1 <= N! <= B^m 根据这个公式求出 M
每个数必然可以分为素数相乘 最后看含有进制的素数有多少个 找到最小的一个输出
例如 : 10 10
进制数 10 含有 2 和5 两个素数他们的个数都是1个 10的阶乘中含有 2 和5 的个数分别为: 9 ,1; 所以10的阶乘末尾在10进制下有1个零
下面看代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long
#define MAX 0xffffffff
#define eps 1e-9
using namespace std;
LL prime[801],T;
struct P
{
LL c,f,l;
}p[801];
void is_prime()
{
for(LL i = 2; i < 801; i++)
for(LL j = 2; j*i <801;j++)
prime[i*j] = 1;
}
LL Get_d(LL nN, LL nB)
{
double fSum = 0.0;
for (LL i = 2; i <= nN; ++i)
{
fSum += log10(i);
}
fSum /= log10(nB);
return floor(fSum + 1e-9) + 1;
}
/*LL Get_d(LL n,LL b)
{
LL m;
double sum = 0;
for(LL i = 1; i <= n; i++)
sum += log(i);
for(m = 1; ; m++)
{
if(m*log(b)>sum ||fabs(m*log(b)-sum)<eps)break;
}
return m;
}*/
LL Get_zero(LL n, LL b)
{
T = 0;
LL i , j;
for(i = 0; i <= b; i++){p[i].c = p[i].l = 0;}
for(i = 2; i <= b ;i++)//分解进制所含有所有的质数
{
if(prime[i] == 0&&b%i == 0)
{
p[T].f = i;
while(b%i == 0){ p[T].c++; b /= i;}
T++;
}
}
for( i = 1; i <= n; i++)//分解每个阶乘数所含有所有的质数
{
LL k = i;
for( j = 0; j < T; j++)
{
while(k%p[j].f == 0){ p[j].l++;k /= p[j].f;}
}
}
LL z = MAX;
for(i = 0; i < T; i++)
{
p[i].c = p[i].l/p[i].c;
z = min(z,p[i].c);//阶乘末尾有多少个零 木桶效应 输出最小的 一个
}
return z;
}
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOACL
LL N,B;
memset(prime,0,sizeof(prime));
is_prime();
while(scanf("%lld%lld",&N,&B)!=EOF)
{
LL d = Get_d(N,B);
LL zero = Get_zero(N,B);
printf("%lld %lld\n",zero,d);
}
return 0;
}