1、这题交了14次才过,刚开始是TLE,改成筛法求素数后还是TLE,取了n和bin的最小值还是TLE(这是个很重要的优化,如果n是1000000那时间将非常长,只要考虑bin的因子即可,当然,bin超过n时,只要考虑n即可)。仔细检查才发现原来是没考虑n==1的特殊情况导致死循环。(bin是binary的缩写,因为不知道进制的英文,就用二进制代替了。不要在意^_^)
2、后来一直WA,怀疑是log的精度太低,改为log10,再加了1e-9,还是WA,于是想了3天。
3、实在找不出错,最后才发现,n==0的特殊情况出错!0的阶乘等于1!所以此时末尾0的个数是0而不是1!!!改掉之后瞬间AC!
#include <stdio.h>
#include <math.h>
int vis[1000]={0},prime[1000]={0},p[1000]={0},c[1000]={0};
double num=0.0;
int main(void)
{
int i,temp,n,bin,count,j,min,mini;
double ans;
while(scanf("%d%d",&n,&bin)==2)
{
num=0.0;count=0;min=2147483647;
memset(vis,0,sizeof(vis));
if(n==0) {printf("0 1\n");continue;}
if(n==1) {printf("0 1\n");continue;}
mini=(int)sqrt(n+0.5);
if(bin<mini) mini=bin;
for(i=2;i<=mini;i++)
if(!vis[i])
{
prime[count++]=i;
vis[i]=1;
for(j=i*i;j<=bin&&j<=n;j+=i)
vis[j]=1;
}
for(i=2;i<=bin&&i<=n;i++)
if(!vis[i])
prime[count++]=i;
for(i=1;i<=n;i++)
{
temp=i;
for(j=0;j<count;j++)
{
while(prime[j]&&temp%prime[j]==0)
{
p[j]++;
temp/=prime[j];
}
if(temp==1) break;
}
}
temp=bin;
for(j=0;j<count;j++)
while(temp%prime[j]==0)
{
c[j]++;
temp/=prime[j];
}
if(temp==1)
{
for(j=0;j<count;j++)
if(c[j]>0&&p[j]/c[j]<min)
min=p[j]/c[j];
}
else min=0;
for(i=1;i<=n;i++)
num+=log10(i);
ans=num/log10(bin)+1e-9;
printf("%d %d\n",min,(int)ans+1);
memset(p,0,sizeof(p));
memset(c,0,sizeof(c));
memset(prime,0,sizeof(prime));
}
return 0;
}