Uva 11038 - How Many O's?

计算特定范围内数字中0的个数
本文介绍了一种算法来计算从1到任意给定整数之间的数字中0的总数。通过分析数字的各个位数,算法能够高效地找出符合条件的数字,并计算其总和。此方法不仅适用于数学问题解决,还为编程竞赛和算法设计提供了实用技巧。
/*
   输入a,b  求a,b之间数字中0的个数
   
   f(b)   代表1到b(包括b)0的数目
   
   f(b)-f(a-1)就是所求的答案
   
   现在的问题就是怎样求f(x)
   
    f(4294967295)= 429496729+429496720 + 429496700+429496000 + 429490000 + 429400000 + 429000000 + 420000000 +  400000000
    
    f(50000)= 5000+(5000-10+1) + (5000-100+1) +(5000-1000+1)       //5000 +4991 +4901 +4001
    
    找规律:对于其中的某位  if(当n是10的整数倍时),sum+=(n/10+pow(10,(n的从右向左的第几位-1))+1) 
                            else  sum+=这个数右边的位变成 0  如第一个例子所示
    
    这道题 和求1的数目都有相似之处 (下面的来自编程之美) 
    
    LONGLONG Sum1s(ULONGLONG n)

   {

     ULONGLONG iCount=0;

     ULONGLONG iFactor=1;

     ULONGLONG iLowerNum=0;

     ULONGLONG iCurrNum=0;

     ULONGLONG iHigherNum=0;

     while(n/iFactor!=0)

     {

          iLowerNum=n-(n/iFactor)*iFactor;

          iCurrNum=(n/iFactor)%10;

          iHigherNum=n/(iFactor*10);

          switch(iCurrNum)

          {

               case 0:

                    iCount+=iHigherNum*iFactor;

                    break;

               case 1:

                    iCount+=iHigherNum*iFactor+iLowerNum+1;

                    break;

               default:

                    iCount+=(iHigherNum+1)*iFactor;

                    break;

          }

          iFactor*=10;

     }
   return iCount;

} 
                             
    

*/
#include<stdio.h>
long long sum0(long long n)
{ 
  long long sum=0;
  long long k=0;
  long long kk=1;
  while(n>=10)
  {
    long long x=n%10;
     n=n/10; 
    
    if(x==0)
    {
      sum+=(n-1)*kk+(k+1);
      printf("%lld +",(n-1)*kk+(k+1));
    }  
    else
    {
     sum+=n*kk;
     printf("%lld +",n*kk);
   }
    k+=x*kk;
    kk=10*kk;
   }
  return sum; 
}

int main()
{
    long long  n,m; 
  
    while(scanf("%lld%lld",&n,&m)!=EOF)
    {
        if(n<0)break;
        long long x=sum0(m); 
        long long y=sum0(n-1);
        if(n==0)y--;
       
      printf("%lld\n",x-y);                      
                                   
    }
    
return 0;    
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值