“1”的数目

来源:互联网 发布:淘宝访客来源根据 编辑:程序博客网 时间:2024/04/29 20:38

题目:

给定一个十进制正整数N,写下从1开始到N的所有整数,然后数一下其中出现的所有“1”的个数。

例如:

N=2

1,2,只有1个“1”。

N=12

1,2,3,4,5,6,7,8,9,10,11,12,这里有5个“1”。

问题:

写一个函数F(N),返回1到N之间出现的“1”的个数,比如F(5)=12;

解答:这道题要分别统计1到N之间的数个位上是“1”,十位上是“1”,百位上是“1”。。。注意一点:比如111个位十位百位都是“1”要算3次。先看一些例子。

1.一位数的情况

比如:N=5,1,2,3,4,5,只有1个“1”

2.二位数的情况

比如:N=18,个位数上是“1”的有2个分别为1和11,十位数上是“1”的有9个分别为10,11...18。

3.三位数的情况,

比如N=134,个位数上是“1”的有14个;十位数上是“1”的有20个,百位上是“1”的有35个。

。。。

假如N=abcde,a,b,c,d,e分别是十进制数N各个位上的数字。现在计算百位上是“1”的个数。其实就是计算()()1()()这样一个数,使其不超过N有多少个。

如果c=0,比如N=13045,如果是三位数:1()(),最后2个()都可以取0-9有100个,如果是()1()()四位数,第一个()只能取1-9,故有900个,如果是五位数()()1()()这种形式肯定是(1)(0-2)1()()有300个。总共有100+900+300=1300。

如果c=1,比如N=15125,分析如上,如果是三位数:1()(),有100个,如果是四位数()1()()有900个,如果是五位数()()1()()只能是这样(1)(0-4)1()()或(1)(5)1()()最后二位不超过25,所以有526个。总共有100+900+526=1526个。

如果c>1,比如N=13686,分析同上,如果是三位数:1()(),有100个,如果是四位数()1()()有900个,如果是五位数()()1()(),只能是这种形式(1)(0-3)1()()有400个。总共有100+900+400=1400。

从上面可以看到求某个位上是“1”,与当前位,高位,低位都有关系。如果当前位是“0”,就是高位*该位的基(个位是1,十位是10,百位是100。。。);如果当前位“1”,就是高位*该位的基+低位+1;如果当前位既不是“0”也不是'1",就是(高位+1)*该位的基。

long long int Count(long long int N){long long int sum=0;long long int Factor=1;long long int CurrentNum=0;long long int LowerNum=0;long long int HigherNum=0;while(N/Factor!=0){LowerNum=N-(N/Factor)*Factor;CurrentNum=(N/Factor)%10;HigherNum=N/(Factor*10);switch(CurrentNum){case 0:sum+=HigherNum*Factor;break;case 1:sum+=HigherNum*Factor+LowerNum+1;break;default:sum+=(HigherNum+1)*Factor;}Factor=Factor*10;}return sum;}

0 0