具体见《编程之美》
解法一:从1到N遍历,求每个数中1的个数加和
int Count1InInteger(int n)
{
int num=0;
while(n)
{
num+=(n%10 == 1)?1:0;
n/=10;
}
return num;
}
int f(int n)
{
int count=0;
for(int i=1; i<=n; i++)
{
count+=Count1InInteger(i);
}
return count;
}
解法二:
从1到N将每一位上1的个数加和
对于当前位,规律:
1. 如果当前为0,则此位上出现1的次数只由更高位决定,且等于更高位数字*当前位数。如12013中的百位出现1的个数为12*100;
2. 如果当前为1,则此位上出现1的次数不仅受更高位影响,还受低位影响。等于更高位数字*当前位数+低位数字+1。如12113中的百位出现1的个数为12*100+13+1(编程之美上这地方是不是有点小错误?);
3.其他情况,则此位上出现1的次数仅由高位决定,且等于(更高位数字+1)*当前位数。如12213中的百位出现1的次数为(12+1)*100。
int Sum1s( int n)
{
int count=0;
int factor=1;
int lowernum=0, curnum=0, higernum=0;
while(n/factor)
{
lowernum=n-(n/factor)*factor;
curnum=(n/factor)%10;
higernum=n/(factor*10);
switch(curnum)
{
case 0:
count+=higernum*factor;
break;
case 1:
count+=higernum*factor+lowernum+1;
break;
default:
count+=(higernum+1)*factor;
}
factor*=10;
}
return count;
}