UVa OJ 10061

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值