要计算1的数量,首先发现f(1)=1,f(2)=1,f(10)=2,f(11)=3,f(13)=5,f(23)=13=2+1+10,f(33)=3+1+10=14,f(99)=9+1+10=20,f(123)=20+24+13=57,可以看出我们先计算个位上1出现的次数,在十位上出现的次数,以此类推,最后全部相加起来,就可以得到最后的次数。
1 #include<iostream> 2 #include<cmath> 3 using namespace std; 4 5 int sum(int shu) 6 { 7 int a=1;//标记计数1的位数 8 int b=0;//当前位数数字 9 int c=0;//较低位数字大小(可为多位) 10 int d=0;//较高位数字大小 11 int count=0; 12 while(shu/a!=0) 13 { 14 //获取数字 15 b=(shu/a)%10; 16 c=shu-(shu/a*a); 17 d=shu/(a*10); 18 if(shu<=0) 19 return 0; 20 if(0==b)//当前数字为0时计数 21 { 22 count+=d*a; 23 } 24 else if(1==b)//当前数字为1时计数 25 { 26 count+=d*a+c+1; 27 } 28 else 29 { 30 count+=(d+1)*a; 31 } 32 a=a*10;//数字左移一位 33 } 34 return count; 35 } 36 void main() 37 { 38 int shu; 39 int max=0; 40 while((cout<<"请输入要测试的数值(输入0结束测试):")&&cin>>shu) 41 { 42 if(shu==0) 43 break; 44 cout<<"1到"<<shu<<"包含的1个数:"<<sum(shu)<<endl; 45 } 46 }
虽然用遍历的的方法也是可以做,但明显可以感觉到当n足够大时,花费的时间就会越来越长,而这样同构考虑每一个位数,就会变得十分简单