原创:转载请注明出处::http://blog.csdn.net/u014686462/article/details/37889583
看了几篇博文加题解,还是无法弄懂代码的含义。所以自己慢慢推,输出中间结果,终于知道啥回事了。
首先思路就是找K的所有质因子存在数组 p[cnt]里 ,该质因子的个数存在数组 num[cnt]里,对每num[i] 个质因子 p[i],
看N!能贡献多少组这样的。最终得到的最小组数就为答案。
举个例子:
N=1200 K=10
先看看p与num数组里存了些什么。明显有:
//因为10=2*5
p[1]=2,num[1]=1;
p[2]=5,num[2]=1;
然后对于每个质因子,看N!能贡献多少个。
p[1]=2;
1200/2=600;//首先贡献了600个2,参与贡献的数来自于1*2,2*2,3*2,4*2,...600*2(达到了上限)
600/2=300;//然后把上面每个数都除2,所以就是1到600,按照相同的算法,可以贡献300个2.
....
...
.
把所有的贡献个数加起来就知道了1200!贡献了1196个2;
同理....
p[2]=5;
1200/5=240;
...
..
把所有的贡献个数加起来就知道了1200!贡献了298个5;
因为1个2乘1个5才有10,所以最终就是298个0;
过程就是这样的,举个例子然后相信大家都看懂了吧!
最后上代码:
#include<iostream>
#include<algorithm>
#include<map>
#include<string>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
int p[20],num[20],N;
long long pn[20];
void ph(int x)//对x分解质因子
{
int i;
N=0;
memset(num,0,sizeof(num));
memset(p,0,sizeof(p));
for(i=2;i<(int)sqrt(x*1.0)+1;i++)
{
if(x%i==0)
{
while(x%i==0)
{
num[N]++;
x/=i;
}
p[N++]=i;
}
}
if(x>1)
{
num[N]++;
p[N++]=x;
}
}
void eul(long long x)//对于每个质因子,看N!能贡献多少个。
{
int i;
long long res=x;
memset(pn,0,sizeof(pn));
for(i=0;i<N;i++)
{
res=x;
res=res/p[i];
pn[i]=res;
while(res)//就是在不断地除质因子
{
res=res/p[i];
pn[i]+=res;
}
}
}
int main()
{
long long a,n;
char s[100];
int b,i;
while(scanf("%s%d",s,&b)!=EOF)
{
a=0;
for(i=0;i<(int)strlen(s);i++)
{
if(s[i]>='A'&&s[i]<='Z') a=a*b+s[i]-'A'+10;
else if(s[i]>='a'&&s[i]<='z') a=a*b+s[i]-'a'+36;
else a=a*b+s[i]-'0';
}
ph(b);
eul(a);
n=-1;
for(i=0;i<N;i++)
{
if(n>pn[i]/num[i]||n==-1)//找最小的贡献数
n=pn[i]/num[i];
}
printf("%lld\n",n);
}
return 0;
}