一、题目
给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数。
二、要求
写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数。例如 f(12) = 5。在32位整数范围内,满足条件的“f(N) =N”的最大的N是多少。
三、设计思路
1、首先遍历每个数的各个位数,然后将1的个数加起来。
2、首先找规律: f(1)=1;f(13)=7=2+5;f(23)=13=3+10......f(abcde)=?
以百位为例, 当c是1,那么百位上1的个数是由他的高位和低位来决定的。等于ab*100+cde+1;当c是"0",那么百位上1的个数是ab*100;当c是大于1,那么 百位上1的个数是(ab+1)*100;以此类推。
四、源代码
1.遍历各位1的个数:
1 #include<iostream> 2 using namespace std; 3 int main() 4 {int icount=0,i,N,temp; 5 cout<<"请输入最大的数N:"; 6 cin>>N; 7 for(i=1;i<=N;i++) 8 { 9 temp=i; 10 while(temp!=0) 11 { 12 icount+=(temp%10==1)?1:0; 13 temp/=10; 14 } 15 } 16 cout<<icount<<endl; 17 return 0; 18 }
2、有规律的解决方法:
1 #include<iostream.h> 2 int Count(int n) 3 { 4 int count=0; 5 int now=1; 6 int l=0; 7 int nownum=0; 8 int h=0; 9 if(n<=0) 10 { 11 return 0; 12 } 13 while(n/now!=0) 14 { 15 l=n-(n/now)*now; 16 nownum=(n/now)%10; 17 h=n/(now*10); 18 if(nownum==0) 19 { 20 count+=h*now; 21 } 22 else if(nownum==1) 23 { 24 count+=h*now+l+1; 25 } 26 else 27 { 28 count+=(h+1)*now; 29 } 30 now*=10; 31 } 32 return count; 33 } 34 void main() 35 { 36 int number; 37 cout<<"请输入数字:"; 38 cin>>number; 39 cout<<Count(number)<<endl; 40 }
四、运行截图
五、实验总结
首先想到的是遍历各个位数,再统计1的个数,但是这样设计的算法时间复杂度比较高,如果找出一个规律的话就可以将问题简化,进而降低时间复杂度复杂度。