一、题目
给定一个十进制的正整数,写下从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 #include2 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 else28 {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的个数为:"< <
五、运行截图
六、实验总结
通过本次课堂联系,让我学习到了在遇到类似问题的时候应该先举例运算,并在计算过程中找出规律,根据找出的规律
通过代码来实现题目的要求。