一、题目
给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数出其中1的个数。
二、要求
1、写一个函数F(N),返回1~N之间出现“1”的个数,例如:F(12)=5;
2、在32位整数范围内,满足条件的“F(N)=n”的最大的N是多少;
三、思路
情况1:如果百位上的数字为0,则可以知道百位上可能出现1的次数由更高位决定,比如12 013,则可以知 道百位出现1的情况可能是100-199,1 100-1 199,……,11 100-11 199,一共有1 200个。也就是 由更高位数字(12) 决定,并且等于更高位数字(12)×当前位数(100)。
情况2:如果百位上的数字为1,则可以知道,百位上可能出现1的次数不仅受更高位影响,还受低位影响, 也就是由更高位和低位共同决定。例如12 113, 受更高位影响,百位出现1的情况是100-199,1 100 -1 199,……,11 100-11 199,一共有1 200个,和上面第一种情况一样,等于更高位数字(12)×当前位数(100)。但它还受低位影响,百位出现1的情况是12 100-12 113,一共114个,等于低位数字 (113)+1。
情况3:如果百位上数字大于1(即为2-9),则百位上可能出现1的次数也仅由更高位决定,比如12 213,则 百位出现1的情况是:100-199,1 100-1 199,……,11 100-11 199,12 100-12 199,共1300个 ,并且等于更高位数字+1(12+1)×当前位数(100)。
四、程序源码
1 #include <iostream.h> 2 3 long int Find(int n) 4 { 5 long int count=0; //1的个数 6 long int F=1; //当前位 7 long int LNum=0; //低位数字 8 long int CNum=0; //当前数字 9 long int HNum=0; //高位数字 10 if(n<=0) 11 { 12 return 0; 13 } 14 while(n/F!=0) 15 { 16 LNum=n-(n/F)*F; //低位数字 17 CNum=(n/F)%10; //当前数字 18 HNum=n/(F*10); //高位数字 19 if(CNum==0) 20 { 21 count +=HNum*F; 22 } 23 else if(CNum==1) 24 { 25 count+=HNum*F+LNum+1; 26 } 27 else 28 { 29 count+=(HNum+1)*F; 30 } 31 F*=10; 32 } 33 return count; 34 } 35 36 int main() 37 { 38 long int n; 39 cout<<"请输入一个数n(n>0):"; 40 cin>>n; 41 cout<<"1的个数为:"<<Find(n)<<endl; 42 return 0; 43 }
五、运行截图
六、实验总结
通过本次课堂联系,让我学习到了在遇到类似问题的时候应该先举例运算,并在计算过程中找出规律,根据找出的规律
通过代码来实现题目的要求。