NYOJ 514(整数中的1)

有篇博文写的是统计二进制中1的个数和,这篇是统计区间内十进制的1的个数和,题目链接:NYOJ 514

先讨论下1到n间的1的个数和。给你一个数如:384,求1~384的1的个数之和。

那么我只需求出1~300中1的个数和+1~80中1的个数和+1~4中1的个数和。

1~4的1的个数为1,1~80中1的个数为101(十位数)+8*100(个位数)----十位数有10,11,12,13....19(共10个数--其中11后面的1作为个位数看待),个位数为1,11,21,31...71,共有8个1,同理可得1~300中的1的个数102(百位数--只有以1开头的数)+3*101(十位数)+30*100(个位数)。

要特别注意的是当你的求的这一位是1的时候要特别处理,比方说N=187,这个时候百位上的1的个数就不是100了,而是88个(100-187)=N/102+1。

化简以一下,求1~a000000(假设共有k位)中1的个数(a!=1),那么个数为:10k-1+a*10k-2+10*a*10k-3+....+10k-1*a*100=10k-1+a*(k-1)*10k-2

那么代码就很简单了,下面Count(n)是求1到n中1的个数和。

那么我要求[a,b]间所有的1的个数和,那么就相当于求Count(b)-Count(a-1)的值。

#include<iostream>
using namespace std;
int low,high;
int Pow[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
int Count(int n)
{   int digit=0,temp=n,sum=0;
    while(temp)
    {   if(temp%10>1) sum+=Pow[digit];
        else if(temp%10==1) sum+=n%Pow[digit]+1;
        sum+=temp%10*digit*Pow[digit-1];
        temp/=10,digit++;
    }
    return sum;
} 
int main()
{   while(cin>>low>>high,low+high)
    {   if(low>high) swap(low,high);
        cout<<Count(high)-Count(low-1)<<endl;
    }
    return 0;
}



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章