有篇博文寫的是統計二進制中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;
}