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



 

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